# Why can't I use \newfloat more than once?

I've found the float package, which lets me specify \newfloat{program}{...} to get other named floats than Table and Figure. However, if I try to use this more than once, I get a cryptic error:

! You can't use \def' after \the.
\fs@plain ->\def
\@fs@cfont {\rmfamily }\let \@fs@capt \floatc@plain \def \@...


It points to the first line where I try to use one of the new floats - not where I define the second one. However, if I remove all calls to \newfloat except one, everything works as expected.

Is this a problem with the package? If so, is there another package I can use that does the same thing (and doesn't depend on this package)?

UPDATE: This seems to be related to using the listings package in new floats. The following code produces the above error:

\documentclass{article}

\usepackage{floatrow}
\DeclareNewFloatType{program}{name=Program,fileext=lop,within=section}
\DeclareNewFloatType{output}{name=Output,fileext=loo,within=section}

\usepackage{listings}

\begin{document}

\begin{program}
\lstinputlisting{thisfile.tex}
\caption{some code}
\end{program}

\end{document}


If I comment out the second \DeclareNewFloatType, or do something else in the float (for example \begin{tabular}...\end{tabular} instead of \lstinputlisting{...}), the code compiles correctly.

-
Are you trying to use \newfloat{program}{...} multiple times or do you have \newfloat{program}{...} \newfloat{foo}{...}? – TH. Sep 5 '10 at 2:58
As TH's comment sort of implicitly suggests: Could you include a bit more detail about what you're trying to do (and, ideally, a minimal complete example that illustrates the problem)? – Brooks Moses Sep 6 '10 at 5:18
You've now posted a bounty, but you still haven't added the extra detail that we have asked for. – TH. Sep 23 '10 at 20:54

You've had a couple of answers, but I think a careful analysis points to a specific issue. In LaTeX2e, the way that environments work is by defining macros called \<name> and \end<name> although the later is optional). This is important because \output is the name of a TeX primitive, so declaring an environment called output will overwrite the primitive with the new definition.

In most circumstances this will not show up as LaTeX has already done what it needs to do with \output before you load anything at all (it's in the kernel). However, the listings package wants to alter the behaviour of \output, and that is where the issue comes in. The new definition (for the environment) is fundamentally different from the old one (the primitive) and it is this that leads to the errors.

The net result is that you cannot safely call an environment output. Overwriting the primitive here is just too risky. (With my LaTeX3 hat on, this is a reason why we plan to save all of the primitives with new, internal, names, and also why we plan to implement environments in a safer way.)

-
I believe that \output is not a primitive, it's just a token list (of course a very special one). – dıʞsdoʇ Sep 25 '10 at 6:58
No, it is: try \show\output. \output is one of the special token registers built into TeX, along with things like \everypar, \everymath, etc. – Joseph Wright Sep 25 '10 at 8:28
+1 for careful analysis. I think this should be the accepted answer because it answers the question instead of providing workarounds. – Philipp Sep 25 '10 at 10:36
Thanks! This did indeed solve my problem - I just called the environment "poutput" instead of "output", and everything works like a charm! =) – Tomas Lycken Sep 25 '10 at 10:39

The listings package already has the ability to float programs. Try

\lstinputlisting[float,caption=some code]{thisfile.tex}


If you want these to be called Programs instead of Listings, then you can use

\renewcommand\lstlistlistingname{Programs} % Header for the List of Listings
\renewcommand\lstlistingname{Program} % Caption label


To define a new environment, you should use

\lstnewenvironment{program}{}{}


which is similar to LaTeX's \newenvironment. Take a look in the listings documentation for details. As Joseph notes, you cannot use output as a name, so you'll need to work around that by picking a different name.

-
 This is good to know! However, in this case I want to list program code and output in different ways, so I still need to differentiate between them. – Tomas Lycken Sep 25 '10 at 9:42 @Tomas Lycken: Sure. You can explicitly set the caption label for each code listing by using the title optional argument instead of caption, but that seems like a hassle. For the output, see Joseph Wrights's excellent answer. – TH. Sep 25 '10 at 10:11

Try the \DeclareNewFloatType command of the floatrow package (see p. 63 of the documentation for details).

\documentclass{article}

\usepackage{floatrow}
\DeclareNewFloatType{example}{name=Example,fileext=loe}
\DeclareNewFloatType{map}{name=Map,fileext=lom,within=section}

\begin{document}

\section{A section}

\begin{example}[!ht]
\caption{An example}
\end{example}

\begin{map}[!ht]
\caption{A map}
\end{map}

\end{document}

-
 I've tried this, but since floatrow uses float` under the hood, I get the same error. – Tomas Lycken Sep 22 '10 at 22:59 I can compile the code above without any errors. Could you post a small example that produces the error you're talking about? – Juan A. Navarro Sep 23 '10 at 11:49