jneug / typst-codelst

A typst package to render sourcecode
MIT License
79 stars 4 forks source link

Allow to pass content into sourcecode #5

Closed likern closed 3 months ago

likern commented 11 months ago

Hello! Thanks for your project, it's awesome.

I'm trying to customize my source code as shown on picture below. Screenshot from 2023-08-06 16-16-25

Not only using codelst and showybox, but also highlight some groups inside raw text using

 #figure(
    [
      #show raw: set text(font: "IBM Plex Mono", size: 12pt)
      #show regex("#"): set text(fill: orange.darken(50%))
      #body
    ],
    caption: title,
    supplement: supplement,
    kind: kind
  ) #if labl.len() > 0 { label(labl) }

so instead of passing raw text into sourcecode function I want to pass content into it. But seems it only supports raw text.

If there is other way to achieve this please let me know, I might be doing something wrong.

likern commented 11 months ago

This is the whole function to experiment with

#let code(body, title: "", lines: (), is-block: true, codelabel: "test") = {
  if is-block {
    show figure.where(kind: "code"): (fig) => {     
      let content = showybox(
        title: [#fig.caption #h(1fr) #fig.supplement #fig.counter.display()],
        title-style: (
          color: black.lighten(30%),
          weight: "regular"
        ),
        frame: (
          title-color: gray.lighten(85%),
          body-color: gray.lighten(95%),
          border-color: gray.lighten(85%)
        )
      )[#fig.body]
      [#content]
    }

    [
      #figure(
        [
          //#show raw: set text(font: "IBM Plex Mono", size: 10pt)
          #show raw: set text(font: "IBM Plex Mono", size: 12pt)
          #show regex("#"): set text(fill: orange.darken(50%))
          #body
        ],
        caption: title,
        supplement: "Example",
        kind: "code"
      ) #label(codelabel)
    ]

  } else {
    show raw.where(block: false): box.with(
      fill: luma(240),
      inset: (x: 3pt, y: 0pt),
      outset: (y: 3pt),
      radius: 2pt,
    )

    [#body]
  }
}
jneug commented 8 months ago

Hi @likern, I'm not sure how this relates to codelst since your example does not use #sourcecode.

maucejo commented 3 months ago

Hi @jneug, I have the same problem as @likern. I don't figure out how to add parameters when combining codelst and showybox. I am pretty sure that it is due to my lack of understanding of the pcoding feature of Typst. Here is a MWE:

#let code = {
    sourcecode.with(
    frame: (body) => showybox(
      title: [*Code*],
      frame: (
        title-color: red,
        border-color: red,
        body-color: none,
        thickness: (left: 3pt),
        radius: (top-left: 0pt, bottom-right: 1em, top-right: 1em),
      ),
     body
    )
)}

The previous function is adapted from the documentation of codelst. However, what I am looking for is something like:

#let code(language: none, body) = {
    sourcecode.with(
    frame: showybox(
      title: [*Code* #h(1fr) #strong(language)],
      frame: (
        title-color: red,
        border-color: red,
        body-color: none,
        thickness: (left: 3pt),
        radius: (top-left: 0pt, bottom-right: 1em, top-right: 1em),
      ),
    body
    )
)}

Do you have any advice? Thank you

jneug commented 3 months ago

Your error is with the use of with. In the first example (from the docs) the variable code is set to the result of the sourcecode.with call, which is a function with a new default argument for frame. Essentially, code becomes an alias for sourcecode with some new defaults.

In your example, you create a new function named code that has two parameters (language and body). Not the use of paranthesis (( and )) before the equals sign. This way, code is its own function and not an alias for sourcecode. It will execute every statement in its body and call sourcecode.with, which again returns a function. But in this case, the returned function is not called and the result if code is a function itself.

Here is a working code example:

#let code(language: none, body) = sourcecode(
    frame: showybox.with(
      title: [*Code* #h(1fr) #strong(language)],
      frame: (
        title-color: red,
        border-color: red,
        body-color: none,
        thickness: (left: 3pt),
        radius: (top-left: 0pt, bottom-right: 1em, top-right: 1em),
      )
    ),
    body
)
maucejo commented 3 months ago

Thank you @jneug , the solution was easier than I thought. I think we can close this issue since it seems to also answer the question of @likern.