How can I create a separator that doesn't show up on the bottom of a page or colum?

I have a function that (among other things) makes a section that ends with a horizontal line. It looks good in the middle of a page/column but not when the line is the last thing on the page/column.

#let separator = align(center)[
  #block(above: 0.5em, below: 1em)[
    #line(length: 80%, stroke: 0.5pt + rgb("dee2e6"))
  ]
]

#let section(title, content) = block(breakable: false, width: 100%)[
  == #title
  #content
  #separator
]

Is it possible to make it automatically not render the separator if it’s the last thing on the page/column?

Could you please share the function you already wrote to add a horizontal line at the end of sections? If this already works and you are only looking for a modification to cover the end-of-page edge case, it makes it a lot easier for someone to help you.

I’ve added an example to the question.

Since the 0.15 release, the idiomatic way to add the separator would be through new divider element, which can be styled:

#show divider: set block(above: 0.5em, below: 1em)
#show divider: set line(stroke: 0.5pt + rgb("dee2e6"), length: 80%)
#show divider: set align(center)

Onto the question: You can measure the divider’s position on the page, and display it conditionally:

#show divider: it => layout(container => {
  // hides the divider if it is too low on the page
  let relative-pos = here().position().y - top-margin()
  let divider-height = measure[. #it .].height -measure[.].height - block.above.to-absolute()
  
  if relative-pos <= container.height - divider-height {
    it
  }
})

Hello! #divider()  // Always displays
#v(645pt)    
Hello! #divider()  // displays if the above is 645pt, but not 646
Hello!

Similarly, you can hide it if it is at the very top of the page by changing the if-condition to if relative-pos > 0pt and relative-pos <= container.height - divider-height

Top margin calculation
// requires context!
#let top-margin() = if page.margin == auto {
  2.5 / 21 * calc.min(page.width, page.height)
} else if type(page.margin) == relative {
  page.margin
} else if page.margin.top == auto {
  2.5 / 21 * calc.min(page.width, page.height)
} else {
  page.margin.top
}
3 Likes

Very sad they did not call it a dinkus:wink: At the same time, I had to re-google the description of it in order to search for my own post about that so I guess divider makes more sense :sweat_smile:

Back in line! :back:

Thank you for your response!

My sections are no-break. Because of that a section can move to the next column/page if it gets too long. What I want is to not draw a divider/separator if it’s the last thing in the column/page so they are only drawn between sections.

This solution assumes there is some distance from the bottom/top that does this but that isn’t the case for me.

Actually, I was wrong and you were right. By putting the divider at the top of my section I can just make sure to not draw a divider at the top and that solved my problem. Thanks!