Codly: full width code box with hanging line numbers

I’m starting to replace my ad-hoc solutions to code display with a systematic use of Codly. I’m quite happy with the package so far, but there’s one thing I haven’t been able to reproduce: a code box in full page width with hanging line numbers:

Any hint on how to tweak Codly’s parameters to achieve this?

Usually this can be achieved using raw.line, but since you’re unifying your code for use of codly alone, I’m only shifting focus there as well.

From its GitHub, it’s evident that the feature came about from Numbers outside margin by pmudry · Pull Request #60 · Dherse/codly · GitHub. At the moment, this can be found in the example 2.32.1, see for yourself:

#codly(number-placement: "outside"):

Thanks, but I’m not quite following. I am using the “outside” placement. My issue is to make the box as wide as the line width, with the number sticking in the margin.

Sorry, I couldn’t tell how familiar you are with the package.

I’m afraid the existing codly features alone don’t support this styling. For example, moving numbers to the left via number-format: (number) => place(dx: -0.5em, str(number)) hides them behind a white block, which is obviously not desired here, but also the code block doesn’t compensate for that space difference.

So I suggest you file a feature request in codly repository or apply your own changes by copying package files for the time being. Hopefully I overlooked something and I’m simply wrong.

Hi. It looks like you’d have to trade one ad-hoc solution for another, to make it work with Codly.

#import "@preview/codly:1.3.0": *

#set par(justify: true)
#show: codly-init
#codly(
  number-align: right,
  number-placement: "outside",
  zebra-fill: none,
  stroke: stroke(0pt),
  radius: 0pt,
)

#show raw.where(block: true): it => context {
  let stroke = 1pt
  let inset = 0.32em
  let magic-padding = 3.87pt
  let max-line-number = calc.max(..it.lines.map(it => it.number))
  let max-line-number-width = measure(raw(str(max-line-number))).width
  let offset = max-line-number-width + inset.to-absolute() * 2 + magic-padding
  // show grid.cell.where(x: 0): it => context panic(measure(it))
  // let offset = 13.75pt
  set block(stroke: stroke)
  show grid: set block(stroke: 0pt)
  show: move.with(dx: -offset)
  it
}

#lorem(50)
#raw(block: true, range(10).map(_ => lorem(10)).join("\n"))
#lorem(50)
#raw(block: true, range(3).map(_ => lorem(10)).join("\n"))
#lorem(50)

I tried figuring out the exact width, but I don’t know where the magic-padding length comes from. And the stroke kinda magically works, without move the stroke disappears. Thankfully, it doesn’t need any width manipulation. So it’s a mess, but so far looks promising. Only a real use case can show if it’s robust enough to not care much about the existence of this hack. A native feature would be better anyway.

So far, it doesn’t work with zebra-fill, because it still fills only inner blocks, but not the stroked one.

2 Likes