A 5.9MB OCaml binary that renders SX pages directly using SDL2 + Cairo, bypassing HTML/CSS/JS entirely. Can fetch live pages from sx.rose-ash.com or render local .sx files. Architecture (1,387 lines of new code): sx_native_types.ml — render nodes, styles, layout boxes, color palette sx_native_style.ml — ~40 Tailwind classes → native style records sx_native_layout.ml — pure OCaml flexbox (measure + position) sx_native_render.ml — SX value tree → native render nodes sx_native_paint.ml — render nodes → Cairo draw commands sx_native_fetch.ml — HTTP fetch via curl with SX-Request headers sx_native_app.ml — SDL2 window, event loop, navigation, scrolling Usage: dune build # from hosts/native/ ./sx_native_app.exe /sx/ # browse sx.rose-ash.com home ./sx_native_app.exe /sx/(applications.(native-browser)) ./sx_native_app.exe demo/counter.sx # render local file Features: - Flexbox layout (row/column, gap, padding, alignment, grow) - Tailwind color palette (stone, violet, white) - Rounded corners, borders, shadows - Text rendering with font size/weight - Click navigation (links trigger refetch) - Scroll with mouse wheel - Window resize → re-layout - URL bar showing current path Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
38 lines
1.1 KiB
OCaml
38 lines
1.1 KiB
OCaml
(** HTTP fetcher for SX pages.
|
|
|
|
Uses curl via Unix.open_process_in for simplicity.
|
|
Fetches pages from sx.rose-ash.com with SX-Request headers. *)
|
|
|
|
let base_url = "https://sx.rose-ash.com"
|
|
|
|
(** Fetch a URL and return the response body as a string. *)
|
|
let fetch_url (url : string) : string =
|
|
let cmd = Printf.sprintf
|
|
"curl -s -L -H 'Accept: text/sx' -H 'SX-Request: true' '%s'" url in
|
|
let ic = Unix.open_process_in cmd in
|
|
let buf = Buffer.create 8192 in
|
|
(try while true do Buffer.add_char buf (input_char ic) done
|
|
with End_of_file -> ());
|
|
ignore (Unix.close_process_in ic);
|
|
Buffer.contents buf
|
|
|
|
(** Fetch an SX page by path (e.g. "/sx/" or "/sx/language"). *)
|
|
let fetch_page (path : string) : string =
|
|
let url = if String.length path > 0 && path.[0] = '/' then
|
|
base_url ^ path
|
|
else if String.length path > 4 && String.sub path 0 4 = "http" then
|
|
path
|
|
else
|
|
base_url ^ "/" ^ path
|
|
in
|
|
fetch_url url
|
|
|
|
(** Read a local .sx file. *)
|
|
let read_file (path : string) : string =
|
|
let ic = open_in path in
|
|
let n = in_channel_length ic in
|
|
let buf = Bytes.create n in
|
|
really_input ic buf 0 n;
|
|
close_in ic;
|
|
Bytes.to_string buf
|