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