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 (fn
() ()
(let (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") (expect-kw! "to")
(let (let
((value (parse-expr))) ((value (parse-expr)))
(let (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 (let
((tgt (parse-tgt-kw "on" (list (quote me))))) ((tgt nil))
(if (if
dur dur
(list (quote transition) prop value dur tgt) (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 ;; 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 (defisland
~pretext-demo/live ~pretext-demo/live
@@ -16,9 +13,51 @@
(canvas (host-call doc "createElement" "canvas")) (canvas (host-call doc "createElement" "canvas"))
(ctx (host-call canvas "getContext" "2d"))) (ctx (host-call canvas "getContext" "2d")))
(let (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 (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 (div
(~tw :tokens "space-y-4") (~tw :tokens "space-y-4")
(div (div
@@ -72,7 +111,7 @@
(let (let
((lines (deref layout)) ((lines (deref layout))
(lh (* (deref font-size) 1.5)) (lh (* (deref font-size) 1.5))
(mw (deref max-w)) (mxw (deref max-w))
(sz (deref font-size))) (sz (deref font-size)))
(div (div
:class "relative rounded-lg border border-stone-200 bg-white overflow-hidden" :class "relative rounded-lg border border-stone-200 bg-white overflow-hidden"
@@ -118,4 +157,6 @@
(span (span
:class "text-xs text-stone-400" :class "text-xs text-stone-400"
(str (len lines) " lines")) (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"))))))))))