126 lines
3.6 KiB
Typst
126 lines
3.6 KiB
Typst
#let state-use-pyscript = state("state-use-pyscript", false)
|
|
#let state-pyscript-version = state("state-pyscript-version", none)
|
|
#let state-pyscript-headers = state("state-pyscript-headers", (:))
|
|
#let state-pyscript-interpreters = state("state-pyscript-interpreters", (:))
|
|
#let state-pyscript-default-interpreter = state("state-pyscript-default-interpreter", none)
|
|
|
|
#let get-pep723(script) = {
|
|
script.find(regex(
|
|
//"(?m)^# /// (?P<type>[a-zA-Z0-9-]+)$\s(?P<content>(^#(| .*)$\s)+)^# ///$"
|
|
"(?m)^# /// script$\s(?P<content>(^#(| .*)$\s)+)^# ///$"
|
|
))
|
|
}
|
|
#let parse-pep723(script) = {
|
|
let metadata-section = get-pep723(script)
|
|
if metadata-section == none {
|
|
return none
|
|
}
|
|
let metadata-section = metadata-section.trim(
|
|
"# /// script\n"
|
|
).trim(
|
|
"# ///"
|
|
).replace(regex("(?m)^#(| )"), "")
|
|
toml(bytes(metadata-section))
|
|
}
|
|
|
|
// TODO DOCUMENT THIS!
|
|
|
|
#let pyscript-show(it) = {
|
|
let metadata = if it.lang != "python" {
|
|
none
|
|
} else {
|
|
parse-pep723(it.text)
|
|
}
|
|
if metadata != none and "pyscript" in metadata.at(
|
|
"tool", default: (:)
|
|
) and metadata.at(
|
|
"tool", default: (:)
|
|
).at(
|
|
"pyscript", default: (:)
|
|
).at(
|
|
"run", default: true
|
|
) {
|
|
state-use-pyscript.update(x => true)
|
|
context {
|
|
let config = metadata.at("tool", default: (:)).at("pyscript", default: (:))
|
|
|
|
let pyscript-config = (:)
|
|
// Package dependencies
|
|
if "dependencies" in metadata {
|
|
pyscript-config.insert("packages", metadata.at("dependencies"))
|
|
}
|
|
// Files stetup
|
|
if "files" in config {
|
|
pyscript-config.insert("files", config.at("files"))
|
|
}
|
|
// Interpreteur selection
|
|
if "interpreter" in config {
|
|
pyscript-config.insert("interpreter", config.at("interpreter"))
|
|
} else if state-pyscript-default-interpreter.final() != none {
|
|
assert(
|
|
state-pyscript-default-interpreter.final() in state-pyscript-interpreters.final(),
|
|
message: state-pyscript-default-interpreter.final() + " is not in pyscript-interpreters",
|
|
)
|
|
pyscript-config.insert("interpreter", state-pyscript-interpreters.final().at(state-pyscript-default-interpreter.final()))
|
|
}
|
|
|
|
let attrs = (
|
|
type: "py"
|
|
)
|
|
if true { // TODO: pygame ?
|
|
attrs.insert("terminal", "")
|
|
attrs.insert("worker", "")
|
|
}
|
|
|
|
if pyscript-config != (:) {
|
|
attrs.insert("config", json.encode(pyscript-config))
|
|
}
|
|
|
|
let script = it.text;
|
|
if config.at("repl", default: false) {
|
|
script = "import code\n" + script + "\ncode.interact(banner='', local=globals())"
|
|
}
|
|
|
|
if not config.at("hide-code", default: false) { //and not config.at("hide-meta", default: false) {
|
|
it
|
|
}
|
|
/* Don't work, will require some way of unsetting show rule of something
|
|
} else if not config.at("hide-code", default: false) and config.at("hide-meta", default: false) {
|
|
let meta-lines = get-pep723(it.text).split("\n")
|
|
let code-lines = it.text.split("\n")
|
|
let meta-line-0 = none
|
|
for i in range(code-lines.len()) {
|
|
let match = true
|
|
for j in range(meta-lines.len()) {
|
|
if (i + j) >= code-lines.len() or meta-lines.at(j) != code-lines.at(i + j) {
|
|
match = false
|
|
break
|
|
}
|
|
if match {
|
|
meta-line-0 = i
|
|
}
|
|
}
|
|
}
|
|
|
|
show raw.line: it => {
|
|
if meta-line-0 == none {
|
|
it
|
|
} else if it.number > meta-line-0 and it.number <= meta-line-0 + meta-lines.len() {
|
|
none
|
|
} else {
|
|
it
|
|
}
|
|
}
|
|
it
|
|
}*/
|
|
|
|
html.elem(
|
|
"script",
|
|
attrs: attrs,
|
|
script
|
|
)
|
|
}} else {
|
|
it
|
|
}
|
|
//raw(block: true, lang: "json", json.encode(metadata))
|
|
}
|