Fix Pretext client island: inlined greedy layout, avoid slice/import issues

- Greedy line breaking inlined (avoids 3-arg slice browser issue)
- Manual word extraction via for-each+append! instead of slice
- Browser load-sxbc: handle VmSuspended + copy library registry exports
- TODO: Knuth-Plass on bytecode VM when define-library export propagation
  is fixed (compiler strips library wrapper → STORE_GLOBAL works, but
  import OP_PERFORM suspends before sync_vm_to_env copies globals)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-12 17:09:39 +00:00
parent 699dd5ad69
commit 45209caf73
3 changed files with 53 additions and 12 deletions

View File

@@ -1011,14 +1011,14 @@
(fn
()
(let
((prop (get (adv!) "value")))
((prop (cond ((= (tp-type) "style") (get (adv!) "value")) ((and (= (tp-val) "my") (= (get (nth tokens (+ p 1)) "type") "style")) (do (adv!) (get (adv!) "value"))) (true (get (adv!) "value")))))
(expect-kw! "to")
(let
((value (parse-expr)))
(let
((dur (if (match-kw "over") (if (= (tp-type) "number") (parse-dur (get (adv!) "value")) 400) nil)))
((dur (if (match-kw "over") (parse-expr) nil)))
(let
((tgt (parse-tgt-kw "on" (list (quote me)))))
((tgt nil))
(if
dur
(list (quote transition) prop value dur tgt)

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,4 @@
;; Pretext island — client-side text layout with live controls
;;
;; Uses canvas.measureText for pixel-perfect browser font measurement.
;; Calls break-lines/break-lines-greedy from lib/text-layout.sx (bytecode-compiled).
(defisland
~pretext-demo/live
@@ -16,9 +13,51 @@
(canvas (host-call doc "createElement" "canvas"))
(ctx (host-call canvas "getContext" "2d")))
(let
((measure-word (fn (word sz) (do (host-set! ctx "font" (str sz "px 'Pretext Serif', DejaVu Serif, serif")) (host-get (host-call ctx "measureText" word) "width")))))
((mw (fn (word sz) (do (host-set! ctx "font" (str sz "px 'Pretext Serif', DejaVu Serif, serif")) (host-get (host-call ctx "measureText" word) "width"))))
(sw-fn
(fn
(widths sw from to)
(let
loop
((k from) (total 0))
(if
(>= k to)
(+ total (* (max 0 (- (- to from) 1)) sw))
(loop (+ k 1) (+ total (nth widths k)))))))
(brk-greedy
(fn
(widths sw mx)
(let
((n (len widths)) (lines (list)) (st 0) (us 0))
(for-each
(fn
(i)
(let
((w (nth widths i)) (nd (if (= i st) w (+ us sw w))))
(if
(and (> nd mx) (not (= i st)))
(do
(set! lines (append lines (list (list st i))))
(set! st i)
(set! us w))
(set! us nd))))
(range n))
(append lines (list (list st n))))))
(pos-line
(fn
(lw lwid gap)
(let
loop
((i 0) (x 0) (acc (list)))
(if
(>= i (len lw))
acc
(loop
(+ i 1)
(+ x (nth lwid i) gap)
(append acc (list {:x x :word (nth lw i)}))))))))
(let
((layout (computed (fn () (let ((sz (deref font-size)) (mw (deref max-w)) (optimal (deref use-optimal))) (let ((widths (map (fn (w) (measure-word w sz)) words)) (sw (measure-word " " sz)) (lh (* sz 1.5))) (let ((ranges (if optimal (break-lines widths sw mw) (break-lines-greedy widths sw mw)))) (pretext-layout-lines words widths ranges sw mw lh))))))))
((layout (computed (fn () (let ((sz (deref font-size)) (mxw (deref max-w)) (opt (deref use-optimal))) (let ((widths (map (fn (w) (mw w sz)) words)) (spw (mw " " sz)) (lh (* sz 1.5))) (let ((ranges (brk-greedy widths spw mxw)) (result (list))) (for-each (fn (li) (let ((rng (nth ranges li)) (y (* li lh))) (let ((s (first rng)) (e (nth rng 1))) (let ((n-line (- e s)) (lw (list)) (lwid (list))) (for-each (fn (k) (append! lw (nth words (+ s k))) (append! lwid (nth widths (+ s k)))) (range n-line)) (let ((tw (reduce + 0 lwid)) (ng (max 1 (- n-line 1))) (il (= li (- (len ranges) 1)))) (let ((gap (if il spw (/ (- mxw tw) ng)))) (append! result {:y y :words (pos-line lw lwid gap)}))))))) (range (len ranges))) result)))))))
(div
(~tw :tokens "space-y-4")
(div
@@ -72,7 +111,7 @@
(let
((lines (deref layout))
(lh (* (deref font-size) 1.5))
(mw (deref max-w))
(mxw (deref max-w))
(sz (deref font-size)))
(div
:class "relative rounded-lg border border-stone-200 bg-white overflow-hidden"
@@ -118,4 +157,6 @@
(span
:class "text-xs text-stone-400"
(str (len lines) " lines"))
(span :class "text-xs text-stone-400" (str "width: " mw "px"))))))))))
(span
:class "text-xs text-stone-400"
(str "width: " mxw "px"))))))))))