Current section
Files
Jump to
Current section
Files
src/docs/utils/codeblock.gleam
import gleam/string
import gleam/list
import gleam/int
import sprocket/html.{code_text, div, ignored, pre}
import sprocket/html/attributes.{class}
pub fn codeblock(language: String, body: String) {
div(
[class("not-prose overflow-x-auto text-sm")],
[
ignored(pre(
[],
[
code_text(
[class("language-" <> language <> " rounded-lg")],
process_code(body),
),
],
)),
],
)
}
pub fn process_code(code: String) {
// trim leading and trailing whitespace
let code =
code
|> string.trim()
// normalize leading whitespace to the minimum amount found on any single line
let min_leading_spaces =
code
|> string.split("\n")
|> list.fold(
0,
fn(acc, line) {
case acc, count_leading_spaces(line, 0) {
0, count -> count
_, 0 -> acc
_, count -> int.min(acc, count)
}
},
)
code
|> string.split("\n")
|> list.map(fn(line) {
case string.pop_grapheme(line) {
// check if the line has leading whitespace. if so, trim it to the minimum
// amount found on any single line. otherwise, return the line as-is.
Ok(#(" ", _)) -> {
string.slice(
line,
min_leading_spaces,
string.length(line) - min_leading_spaces,
)
}
_ -> line
}
})
|> string.join("\n")
}
fn count_leading_spaces(line: String, count: Int) {
case string.pop_grapheme(line) {
Ok(#(" ", rest)) -> count_leading_spaces(rest, count + 1)
_ -> count
}
}