Can floating content (via figure or place) be broken across pages?

Hi all,

If I am right, the expected behaviour of the ‘place’ function is that the content it contains cannot be split if its height is greater than that of the page.

When I was developing the ‘elsearticle’ template, I had some problems, since I wanted double-column content while the title and abstract were single-column. My current solution is to define show: columns(2, body) in the last line of the template.

However, this has a side effect: we have to use colbreak() instead of pagebreak() to insert a manual page or column break.

Another solution is to set the page to two columns and use the place function. This solves the page/column break issue, but unfortunately it only works when the abstract remains on the first page.

My question is: is it possible to have the best of both worlds?

Thank you for your help and suggestions

1 Like

Using #set page(columns: 2) is indeed the “right” way to make this kind of layout. As the columns doc says:

If you need to insert columns across your whole document, use the page function’s columns parameter instead. This will create the columns directly at the page-level rather than wrapping all of your content in a layout container. As a result, things like pagebreaks, footnotes, and line numbers will continue to work as expected. For more information, also read the relevant part of the page setup guide.

I don’t think there’s currently support for breaking floating content across pages. Relevant issue: Content in a `place` function is cut off at the bottom of the page · Issue #6325 · typst/typst · GitHub

Could you give a minimal example to reproduce your problem so we can try to find a workaround?

(If the problem is that an abstract can be too large for the first page… I don’t think Elsevier would accept such a paper anyway?)

Thank you for your answer @sijo. I will try to implement a MWE next week. I have indeed read Content in a place function is cut off at the bottom of the page · Issue #6325 · typst/typst · GitHub and it seems that there is no solution at the moment.

As you mentioned, the problem is that the abstract can be too large for the first page. I agree that in the final version of the paper such a long abstract would be rejected, but in the review phase given the margins, the font size and line spacing, such a situation can happen and it is accepted by Elsevier (at least in the journal in which I publish).

I prepared one quickly—I don’t actually think we’ll find a solution, unfortunately… but maybe you or someone is more creative than me:

#set page(paper: "a6")

// approach 1:
#let doc1(abstract, body) = {
  title[Title]

  abstract

  show: columns.with(2)
  body
}

// approach 2:
#let doc2(abstract, body) = {
  set page(columns: 2)

  place(top, float: true, scope: "parent", {
    title[Title]
  
    abstract
  })

  body
}

// single page abstract: works
// #doc1(lorem(80), lorem(180))

// #doc2(lorem(80), lorem(180))

// multi page abstract: second approach fails!
#doc1(lorem(180), lorem(80))

#doc2(lorem(180), lorem(80))  // !!!
1 Like

I am afraid you are right. It is currently impossible to have the best of both worlds. I have tested both approaches and that is why I posted my question :sweat_smile:

@sijo The codesnippets proposed by @ensko are the MWE reproducing the issue. (Thanks @ensko).

If you are “satisfied” with the non-solution, would you mind accepting sijos post though? I didn’t really help solve/explain the situation, and sijo had more context on the problem.

1 Like

Breakable place and figure content would obviously be the desired solution, but if you are only concerned about having to use colbreak() instead of pagebreak(), you could in the meantime override the pagebreak function to act like a colbreak:

#let pagebreak(weak: false) = colbreak(weak: weak)

Actually, I am not personally concerned with this issue but the users of the package are. A PR has been proposed for this purpose. I thought about implementing the solution you propose. I think it is the right thing to do at the moment.