How to create this kind of theorem box? (LaTeX TColorboxes)


Is there any kind of way to make this kind of theorem environment, the title “in” the border above. I achieved this pretty easily in LaTeX with tcolorbox but don’t know if this is doable in typst (it probably is because everything is but my knowledge isn’t there yet). Now, I’m using the ctheorems package but i have no problem switching to a better one if needed.

There are theorion – Typst Universe, thmbox – Typst Universe. For frames, there are colorful-boxes – Typst Universe and showybox – Typst Universe.

@Andrew, while all of these packages seem relevant, I couldn’t see directly in any of their readmes how to achieve the result OP expects. Please add some context and/or concrete applications (i.e. code) to your answer, as per the answering guidelines:

1 Like

The context is that they are relevant. A starting point.

Then you should explicitly state that you are not attempting a full answer but only to give a starting point.

OP could have (very reasonably) understood that one of your links solves the problem outright, and spent longer than necessary to figure out what they’re missing, even though they didn’t even miss anything – the answer simply wasn’t there.

I got it done with just editing the ctheorems source code but thanks for the suggestions anyway!

Nice! Good job on making it work. Don’t hesitate to post your solution here yourself and check that answer as the solution ;)!

It’s quite hacky and hard-coded but i only use one kind of theorem “box” so it’s fine for me, for sure it’s possible to code it more elegantly but I don’t have time for that right know.

#let mythmbox(
  identifier,
  head,
  ..blockargs,
  supplement: auto,
  padding: (top: 0.8em, bottom: 0em),
  namefmt: x => [(#x)],
  titlefmt: strong,
  bodyfmt: x => x,
  separator: [#h(0.1em):#h(0.2em)],
  base: "heading",
  base_level: none,
) = {
  if supplement == auto {
    supplement = head
  }
  let boxfmt(name, number, body, title: auto, ..blockargs_individual) = {
    if not name == none {
      name = [ #namefmt(name)]
    } else {
      name = []
    }
    if title == auto {
      title = head
    }
    if not number == none {
      title += " " + number
    }
    title = titlefmt(title)
    body = bodyfmt(body)
    pad(..padding, block(
      breakable: false,
      fill: none,
      width: 100%,
      radius: 0pt,
      stroke: (thickness: 0.5pt, paint: black),
      inset: 1.2em,
      place(top, dx: -5pt, dy: -20pt, block(
        fill: white,
        inset: (x: 5pt, y: 5pt),
        stroke: 0pt,
      )[
        #text(font: sansfont)[*#title* #name]
      ])
        + body,
    ))
  }
  return thmenv(identifier, base, base_level, boxfmt).with(
    supplement: supplement,
  )
}
#let theorem = mythmbox("theorem", "Theorem", base_level: 2)

Here you go:

#import "@preview/ctheorems:1.1.3": *

#let mythmbox(
  identifier,
  head,
  supplement: auto,
  padding: (top: 0.8em, bottom: 0em),
  namefmt: x => [(#x)],
  titlefmt: strong,
  bodyfmt: x => x,
  base: "heading",
  base_level: none,
) = {
  if supplement == auto { supplement = head }
  let boxfmt(name, number, body, title: auto, ..blockargs_individual) = {
    name = if name != none { namefmt(name) }
    if title == auto { title = head }
    if number != none { title += " " + number }
    title = titlefmt(title)
    let title-body = text(font: "Libertinus Sans")[#title #name]
    body = bodyfmt(body)
    show: pad.with(..padding)
    show: block.with(
      breakable: false,
      width: 100%,
      stroke: (thickness: 0.5pt, paint: black),
      inset: 1.2em,
    )
    place(top, dx: -5pt, dy: -20pt, block(fill: white, inset: 5pt, title-body))
    body
  }
  thmenv(identifier, base, base_level, boxfmt).with(supplement: supplement)
}

#let theorem = mythmbox("theorem", "Theorem", base_level: 2)

#theorem[name][#lorem(20)]

#theorem[#lorem(20)]

If you pretty much use it as is, then this should be good.

I don’t use these, so this looks too quirky for me to touch stuff further. Though I guess I can try:

#import "@preview/ctheorems:1.1.3": *

#let mythmbox(identifier, head, base: "heading", base_level: none) = {
  let boxfmt(name, number, body, title: auto, ..blockargs_individual) = {
    name = if name != none [(#name)]
    if title == auto { title = head }
    if number != none { title += " " + number }
    let title-body = text(font: "Libertinus Sans")[*#title* #name]
    show: pad.with(top: 0.8em, bottom: 0em)
    show: block.with(
      breakable: false,
      width: 100%,
      stroke: (thickness: 0.5pt, paint: black),
      inset: 1.2em,
    )
    place(top, dx: -5pt, dy: -20pt, block(fill: white, inset: 5pt, title-body))
    body
  }
  thmenv(identifier, base, base_level, boxfmt).with(supplement: head)
}

#let theorem = mythmbox("theorem", "Theorem", base_level: 2)
1 Like