#Source Code Listings

117 messages · Page 1 of 1 (latest)

floral quarry
#

bump

#

so you said i'll have to read and then but it in the raw format?

#

but isnt the read already what i want?

golden arrow
#

Read gets the entire file. You then extract the correct lines before calling raw

floral quarry
#

but why do i need to call raw then?

#

thats what i get from the read part

patent relic
#

raw will highlight the code

floral quarry
#

ah i see

golden arrow
#

The easiest would likely be to split on newline

#

Then merge the lines back after

floral quarry
#

which means i would

#

read the whole file -> gets me the code above
slice the get time function with lines 1 to 4 for example
pipe the code into raw to get highlighting
translate it back into sth to actually be able to see it?

golden arrow
floral quarry
#

i dont get how to call the raw then?

patent relic
#

try this: #raw(read(file-name))

floral quarry
#

ah i see

#

but the code isnt highlighted. maybe because it doesnt support python though

#

the raw blocks remove some of the code parts

patent relic
floral quarry
#

ah

#

ah dang you're right

jovial crater
#

you should also define that it should be a block:

floral quarry
#

which i then can slice again, right?

jovial crater
#

#raw(block: true, lang: "python", python-code)

jovial crater
floral quarry
#

the raw block then?

jovial crater
#

python-code.split("\n").slice(0, 4).join("\n")

golden arrow
#

You slice it before putting it in raw

floral quarry
#

gotcha

#

and why could i want to split it on newlines?

golden arrow
#

Because you're looking to show specific lines?

floral quarry
#

right

#
#let python-code = read("../example.py").split("\n").slice(1, 5).join("\n")


#let raw-code = raw(block: true, python-code, lang: "python")

#raw-code
#

thats super little code, i thought that's gonna be so much more though

#

i could place that one into a block and show the line numbers next to it, right? that for sure works somehow

jovial crater
#

here's an example on how you could do line numbers without a package: #discussions message

floral quarry
#

but the code doesnt read from files, i mean i could add it

onyx dove
#

if you write a show rule on raw, it would work on any code blocks, be it read from a different file, or not

#

If you're using a package, you would use the specific package function, instead of raw (or just raw would work if the package just stylises raw)

#

styling has nothing to do with where the code is coming from

floral quarry
#

well but then its not needed since the codelst package does that for me

onyx dove
#

if you use codelst, you can just pass the raw block into sourcecode

#

as #sourcecode(raw-code)

floral quarry
#

why isnt the code on the left as i told the figure to be?

#let code-block = block.with(
    stroke: 1pt,
    inset: 0.65em,
    radius: 4pt
)

#let code-path = "../example.py"

#let raw-code = raw(code-path, block: true, lang: "python")

#let listcode(file, from, to, language: "python") = {
  let read-code = read(file).split("\n").slice(from, to).join("\n")
  let raw-block = raw(block: true, read-code, lang: language)
  raw-block
}

#align(left)[
    #figure(
        code-block(listcode("../example.py", 1, 5)),
        caption: [Hello World]
) <code-listing>
]
#

and is there any way to change the default caption to a Code or SourceCode?

golden arrow
#

there is a supplement parameter

floral quarry
#

right that explains the listing but not the alignment which is stil off

golden arrow
#

you can fix it by wrapping it in a block, but that shouldn't be necessary

#

?render ```
#set page(width: 20cm)
#show figure: it => align(left,block(it))

#figure(
raw("test"),
caption: [Hello World]
)```

golden arrow
#

Likely a bug

floral quarry
#

top and bottom work but not left and right

#

and that one might be another weird one:

#
#let test(file: none, code: none, range: (), lang: "plain") = {
    if code != none {
        let raw-block = raw(block: true, code, lang: lang)
    }else if file != none {
        let read-code = read(file).split("\n").slice(range.first(), range.last()).join("\n")
        let raw-block = raw(block: true, read-code, lang: lang)
        raw-block
    } else {
        panic("No code or file given")
    }
}
#

error on raw(block: true, code, lang: lang)

#

but the code is a string

#

@quasi canyon this is the support thread

quasi canyon
#

Right

#

So

#

Someone had asked me for something similar

#

It can be adapted to have multiple langs

#

Or whatever

#
#let partial-raw(code, lines: ()) = {
  let text
  let lang
  let is-block
  if type(code) == content and code.func() == raw {
    text = code.text
    is-block = code.block
    lang = code.at("lang", default: none)
  } else {
    panic("First argument to 'partial-raw' must be a raw block.")
  }

  let code-lines = text.split("\n")
  let raw-blocks = ()
  let highlighting = none

  for (i, line) in code-lines.enumerate() {
    let should-highlight = i in lines
    if highlighting != should-highlight {
      highlighting = should-highlight
      raw-blocks.push((lang: if should-highlight { lang } else { none }, block: is-block, text: ""))
    }
    raw-blocks.last().text += line + "\n"
  }

  show raw.where(block: true): set block(spacing: 0.65em)
  raw-blocks.map(args => raw(args.remove("text"), ..args)).join()
}

#partial-raw(
  [three backticks here]rs
  pub fn main() {
    let x = 5;
    println!("Hello world!");
    let y = 5;
    println!("Bye world!");
  }
  [three backticks here],
  lines: (0, 1, 4)
)
floral quarry
#

i mean i kinda got it though

#

i just want it to support code from files too

#

and it kinda works as you can see above

#

but i legit dont know what the compiler wants here lmfao

#

it legit tells me that the type is wrong

#

but it for sure isnt

quasi canyon
floral quarry
#

oh dang the type indeed is content

#
#type("python")
#type(code-part)
#

the code part starts with 3 backticks

quasi canyon
#

Then you're providing a raw element

#

To a new raw element

#

Not a string

#

You can use .text to extract the string inside it

floral quarry
#

is there a way to provide only a single element in an array for a range?

#

something like

(1, ) // goes up to the end ```
floral quarry
#

uh 1sec

#

let read-code = read(file).split("\n").slice(range.first(), range.last()).join("\n")

#

that's what i'm doing right now to get the two "points"

#

#code(file: code-path, range: (1, 8), lang: "python")

#

but i essentially want something like: range: (1, ) which then takes the whole code

golden arrow
#

slice(..range)

floral quarry
#

what does the .. do here?

quasi canyon
#

Well that's very smart lol

quasi canyon
floral quarry
#

ahh

quasi canyon
#

.slice(1) vs slice(1, 8)

floral quarry
#

right and for line numbers i could just enumerate and print all of them to the left

#

sounds a bit tricky, will get it i guess haha

golden arrow
#

?render ```
#let test = raw("
Some lines
with indentation
all over the place
").text

#let offset = 5

#show raw.line: it => {
str(it.number + offset) + it.body
}
#raw(test)

golden arrow
#

proof of concept

#

ignore the leading empty lines, just discord not liking backticks

floral quarry
#

is there a way to get the "offset" from the range i have?

#

something like total - range

golden arrow
floral quarry
#

there is no fixed types in typst yet, right?

#

because when i try to type it it's missing argument "self"

#

ah i got it

floral quarry
#
#let file-path = "../example.py"

#let code-example = ```python
def test(name: str) -> str:
    return f"Hello {name}!"

#let code(code: none, file: none, range: (), lang: "python", use-block: true) = {

if code != none {
let raw-code = raw(block: true, code-example.text, lang: "python")

  code-block(raw-code)

} else if file != none {
let read-code = read(file).split("\n").slice(..range).join("\n")
let raw-block = raw(block: use-block, read-code, lang: lang)

  show raw.line: it => {
    str(it.number + range.first() - 1) + h(1em) +  it.text
  }

  code-block(raw-block)

} else {
panic("No code or file provided")
}
}

#code(file: file-path, range: (1, ))
#parbreak()
#code(code: code-example.text)```

#

i dont get why i cant add numbers and get it colored

floral quarry
#

bump

jovial crater
#

it.text is the raw content of the line