0

Inside a macro I would like to establish a new type of float. One of the parameters to be set during that process is \ftype@TYPE, where TYPE is the float type: figure, table, and so on. I know, that \ftype@figure = 1 and \ftype@table = 2 normally are already set in the classes, e.g. report.cls, and I know, that each following float type gets a number, that is double the one before, so the next one would be 4, then 8, then 16 and so on.

What I don't know, though: How can one inside a macro find out, which is the highest float type number already in use -- for not using one twice?

ThorstenL
  • 161
  • \newfloat from float package? – David Carlisle Jul 18 '23 at 23:43
  • @DavidCarlisle Why does it double each time? (I'm just curious.) – cfr Jul 19 '23 at 01:18
  • 1
    @cfr the float type and !htbp allowed positions are packed into a 32 bit integer each item contributing 1 bit ie 1 power of 2 – David Carlisle Jul 19 '23 at 01:55
  • @David Carlisle: My problem is not, to generate a new float manually -- I have already done that and it works. My problem is: I want to write a macro, that generates a new float and therefore uses a not yet used number for \ftype@TYPE. How do I find out, which number is still free, and which one is not, if there are possibly already more floats generated with unknown packages or even from scratch? I don't see, how newfloat can help me with that? – ThorstenL Jul 19 '23 at 15:17
  • @Werner: I am able to define a new float from scratch -- I have done that and it works. But I did it only inside a document, where I knew, which number to take for \ftype@TYPE: There were only floats figure (1) and table (2), so I could safely take 4 for the new float. But what in case I don't know, which floats are already active? – ThorstenL Jul 19 '23 at 15:20
  • 1
    what you are asking is exactly what \newfloat from the float package does, so I was suggesting you use that. Core latex does not keep record of already allocated floats, a class just has to "know", so using the float (or its related newfloat) package to handle the allocation is best. – David Carlisle Jul 19 '23 at 15:27
  • @David Carlisle: In newfloat.sty of the float package I find the passage \newcounter{float@type}
    @ifundefined{c@figure}%
    {\setcounter{float@type}{1}}%
    {\setcounter{float@type}{4}}
    So if I use that with a document, that has already defined a third float, number 4 will be used twice, as far as I see?
    – ThorstenL Jul 19 '23 at 15:45
  • yes that is why I suggest you use newfloat rather than do a separate allocator. latex does not provide one (no space in 1985) and you can not have two competing ones, so it makes sense to use the one from that package which has effectively been the standard float allocator since some time last century. – David Carlisle Jul 19 '23 at 16:13
  • @Davind Carlisle: I remember me starting with LaTeX in 1991 -- resources were much less at that time than nowadays. So I understand now, that it would be much better to establish EVERY new float with newfloat from the package float -- not only in my macro -- because every float established without the package may be a source of future problems? – ThorstenL Jul 19 '23 at 17:48
  • @David Carlisle: Oh sorry, I misspelled your name in the comment above! – ThorstenL Jul 19 '23 at 20:12
  • I'll survive:-) – David Carlisle Jul 19 '23 at 20:30
  • @David Carlisle: That's good! I need you -- and many others as well ... ;-)) – ThorstenL Jul 19 '23 at 20:49

1 Answers1

4

Unfortunately latex does not provide a good answer here. Effectively the float package provides a standard \newfloat allocator but it has to guess the initial state, if you load it after floats other than figure and table are defined then they will be over-written by \newfloat.


If you don't want to force float to be loaded then I would suggest

a) test if \newfloat is defined, and if so use it.

b) if it is not defined set a value to 1 then test the usual suspects and double the value each time one is defined, to get the free number so perhaps test \c@figure\c@table\c@listings\c@algorithm


listings package does a simpler version of the same idea with

\AtBeginDocument{%
\@ifundefined{c@float@type}%
    {\edef\ftype@lstlisting{\ifx\c@figure\@undefined 1\else 4\fi}}
    {\edef\ftype@lstlisting{\the\c@float@type}%
     \addtocounter{float@type}{\value{float@type}}}%
}

so if \newfloat is defined in the preamble it uses the next free number from that allocation, otherwise hope for the best and use 1 or 4 depending whether figures are defined or not.

David Carlisle
  • 757,742
  • Starting from the listings package you cited, I added a definition of the counter float@type (if missing):

    \AtBeginDocument{% @ifundefined{c@float@type}% {\global\newcounter{float@type}% \ifx\c@figure@undefined% \setcounter{float@type}{1}% \else% \setcounter{float@type}{4}% \fi}% {\relax}% \edef\ftype@lstlisting{\the\c@float@type}% \addtocounter{float@type}{\value{float@type}}% }%

    So, if package float is used, like listings it uses the counter, if not, it defines it. Might that be better?

    – ThorstenL Jul 21 '23 at 20:45
  • I still have problems with writing comments: The one above somehow dropped the "@David Carlisle" and I don't know how to format the code ... – ThorstenL Jul 21 '23 at 20:53
  • @ThorstenL You can only @ ping once in a comment and since you did not code-quote the code, the @s are used up. You can inline quote \like this`` but it loses all line breaks so is not good for code – David Carlisle Jul 21 '23 at 21:00
  • Uhmm, I understand ... And how do I code-quote in a comment? In a question or an answer I have the symbol "{}" for that, I can click on, but I missed that in the comment ... I thought, it wasn't possible -- but I see from your comment, it is ... somehow ... – ThorstenL Jul 22 '23 at 22:30