diff --git a/lib/html_body.typ b/lib/html_body.typ index 5ca03b4..fd06526 100644 --- a/lib/html_body.typ +++ b/lib/html_body.typ @@ -4,7 +4,7 @@ #import "./nav_menu.typ": nav-menu, nav-menu-toggle /// Make the body of the webpage -#let html_body( +#let html-body( /// The visible header of the page header: none, /// The footer of the page diff --git a/lib/html_head.typ b/lib/html_head.typ index 1583535..1c5fe31 100644 --- a/lib/html_head.typ +++ b/lib/html_head.typ @@ -3,7 +3,7 @@ #import "./pyscript.typ": state-use-pyscript, state-pyscript-headers, state-pyscript-version /// Generate the html element for the page. -#let html_head( +#let html-head( /// Page url, url, /// Title of the page diff --git a/lib/html_utils.typ b/lib/html_utils.typ index 06810c9..6531b25 100644 --- a/lib/html_utils.typ +++ b/lib/html_utils.typ @@ -24,7 +24,7 @@ js-list.final().join("\n\n") } -#let html_show(body) = { +#let html-show(body) = { show raw: it => { if it.lang == "raw-css" { // remove code and add it to css style diff --git a/lib/main.typ b/lib/main.typ index 30a728f..7103a86 100644 --- a/lib/main.typ +++ b/lib/main.typ @@ -1,8 +1,8 @@ -#import "./html_head.typ": html_head -#import "./html_body.typ": html_body -#import "./html_utils.typ": html_show +#import "./html_head.typ": html-head +#import "./html_body.typ": html-body +#import "./html_utils.typ": html-show #import "./summary.typ": summary, card-list -#import "./pyscript.typ": state-use-pyscript, state-pyscript-headers, state-pyscript-version, pyscript +#import "./pyscript.typ": state-use-pyscript, state-pyscript-headers, state-pyscript-version, pyscript-show #import "./rss.typ": rss #import "./icons.typ" @@ -56,9 +56,10 @@ state-pyscript-headers.update(x => pyscript-headers) state-pyscript-version.update(x => pyscript-version) } - show: html_show + show: html-show + show raw.where(block: true, lang: "python"): pyscript-show html.html(lang: lang, { - html_head( + html-head( url, title, icon: icon, @@ -70,7 +71,7 @@ stylesheets: stylesheets, me-links: me-links ) - html_body( + html-body( logo: logo, header: header, footer: footer, diff --git a/lib/pyscript.typ b/lib/pyscript.typ index d05b3d2..1a72c12 100644 --- a/lib/pyscript.typ +++ b/lib/pyscript.typ @@ -2,26 +2,109 @@ #let state-pyscript-version = state("state-pyscript-version", none) #let state-pyscript-headers = state("state-pyscript-headers", (:)) -#let pyscript( - repl: false, - body -) = { - show raw.where(block: true, lang: "python"): it => { +#let get-pep723(script) = { + script.find(regex( + //"(?m)^# /// (?P[a-zA-Z0-9-]+)$\s(?P(^#(| .*)$\s)+)^# ///$" + "(?m)^# /// script$\s(?P(^#(| .*)$\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) - it - let script = it.text; - if repl { - script = "import code\n" + script + "\ncode.interact(local=globals())" + let config = metadata.at("tool", default: (:)).at("pyscript", default: (:)) + + let pyscript-config = (:) + if "dependencies" in metadata { + pyscript-config.insert("packages", metadata.at("dependencies")) } + if "files" in config { + pyscript-config.insert("files", config.at("files")) + } + + let attrs = ( + type: "py" + ) + if pyscript-config != (:) { + attrs.insert("config", json.encode(pyscript-config)) + } + if true { + attrs.insert("terminal", "") + attrs.insert("worker", "") + } + + 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: ( - type: "py", - terminal: "", - worker: "", - ), + attrs: attrs, script ) + } else { + it } - body + //raw(block: true, lang: "json", json.encode(metadata)) } diff --git a/test_template/main.typ b/test_template/main.typ index 1088745..36b98e2 100644 --- a/test_template/main.typ +++ b/test_template/main.typ @@ -74,35 +74,46 @@ #lorem(400) -#pyscript[ - ```python - for i in range(1, 16): - if i % 3 == 0 and i % 5 == 0: - print("plopliplop") - elif i % 3 == 0: - print("plop") - elif i % 5 == 0: - print("plip") - else: - print(i) - ``` -] -#pyscript(repl: true)[ - ```python - ret = [] - for i in range(16, 31): - if i % 3 == 0 and i % 5 == 0: - ret.append("plopliplop") - elif i % 3 == 0: - ret.append("plop") - elif i % 5 == 0: - ret.append("plip") - else: - ret.append(i) - # >>> print(ret) - # [16, 17, 'plop', 19, 'plip', 'plop', 22, 23, 'plop', 'plip', 26, 'plop', 28, 29, 'plopliplop'] - ``` -] +```python +# /// script +# [tool.pyscript] +# /// +n = "" +while not n.isnumeric(): + n = input("enter a valid number: ") + +for i in range(1, int(n) + 1): + if i % 3 == 0 and i % 5 == 0: + print("plopliplop") + elif i % 3 == 0: + print("plop") + elif i % 5 == 0: + print("plip") + else: + print(i) +``` +```python +# /// script +# # requires-python = ">=3.11" # not supported yet +# dependencies = [ +# "rich", +# ] +# +# [tool.pyscript] +# repl = true +# [tool.pyscript.files] +# "https://peps.python.org/api/peps.json" = "./peps.json" +# /// + +import json +from rich.pretty import pprint + +with open("./peps.json") as fd: + data = json.load(fd) +pprint([(k, v["title"]) for k, v in data.items()][:10]) +# >>> print(data["723"]["title"]) +# Inline script metadata +``` #summ.card