Add Specs section, Reflexive Web essay, fix highlight and dev caching
- Fix highlight() returning SxExpr so syntax-highlighted code renders as DOM elements instead of leaking SX source text into the page - Add Specs section that reads and displays canonical SX spec files from shared/sx/ref/ with syntax highlighting - Add "The Reflexive Web" essay on SX becoming a complete LISP with AI as native participant - Change logo from (<x>) to (<sx>) everywhere - Unify all backgrounds to bg-stone-100, center code blocks - Skip component/style cookie cache in dev mode so .sx edits are visible immediately on refresh without clearing localStorage Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -240,4 +240,42 @@
|
||||
"tail-call-optimization" (~essay-tail-call-optimization)
|
||||
"continuations" (~essay-continuations)
|
||||
"godel-escher-bach" (~essay-godel-escher-bach)
|
||||
"reflexive-web" (~essay-reflexive-web)
|
||||
:else (~essay-sx-sucks)))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; Specs section
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(defpage specs-index
|
||||
:path "/specs/"
|
||||
:auth :public
|
||||
:layout (:sx-section
|
||||
:section "Specs"
|
||||
:sub-label "Specs"
|
||||
:sub-href "/specs/core"
|
||||
:sub-nav (~section-nav :items specs-nav-items :current "Core")
|
||||
:selected "Core")
|
||||
:data (spec-data "core")
|
||||
:content (~spec-core-content :spec-files spec-files))
|
||||
|
||||
(defpage specs-page
|
||||
:path "/specs/<slug>"
|
||||
:auth :public
|
||||
:layout (:sx-section
|
||||
:section "Specs"
|
||||
:sub-label "Specs"
|
||||
:sub-href "/specs/core"
|
||||
:sub-nav (~section-nav :items specs-nav-items
|
||||
:current (find-current specs-nav-items slug))
|
||||
:selected (or (find-current specs-nav-items slug) ""))
|
||||
:data (spec-data slug)
|
||||
:content (if spec-not-found
|
||||
(~spec-not-found :slug slug)
|
||||
(case slug
|
||||
"core" (~spec-core-content :spec-files spec-files)
|
||||
:else (~spec-detail-content
|
||||
:spec-title spec-title
|
||||
:spec-desc spec-desc
|
||||
:spec-filename spec-filename
|
||||
:spec-source spec-source))))
|
||||
|
||||
@@ -16,6 +16,7 @@ def _register_sx_helpers() -> None:
|
||||
"primitives-data": _primitives_data,
|
||||
"reference-data": _reference_data,
|
||||
"attr-detail-data": _attr_detail_data,
|
||||
"spec-data": _spec_data,
|
||||
})
|
||||
|
||||
|
||||
@@ -103,6 +104,63 @@ def _reference_data(slug: str) -> dict:
|
||||
}
|
||||
|
||||
|
||||
_SPEC_FILES = {
|
||||
"parser": ("parser.sx", "Parser", "Tokenization and parsing of SX source text into AST."),
|
||||
"evaluator": ("eval.sx", "Evaluator", "Tree-walking evaluation of SX expressions."),
|
||||
"primitives": ("primitives.sx", "Primitives", "All built-in pure functions and their signatures."),
|
||||
"renderer": ("render.sx", "Renderer", "Rendering evaluated expressions to DOM, HTML, or SX wire format."),
|
||||
}
|
||||
|
||||
|
||||
def _spec_data(slug: str) -> dict:
|
||||
"""Return spec file source and highlighted version for display."""
|
||||
import os
|
||||
from content.highlight import highlight as _highlight
|
||||
|
||||
ref_dir = os.path.join(os.path.dirname(__file__), "..", "..", "shared", "sx", "ref")
|
||||
# Normalise — inside container shared is at /app/shared
|
||||
if not os.path.isdir(ref_dir):
|
||||
ref_dir = "/app/shared/sx/ref"
|
||||
|
||||
base = {"spec-not-found": None, "spec-title": None, "spec-desc": None,
|
||||
"spec-filename": None, "spec-source": None, "spec-files": None}
|
||||
|
||||
if slug == "core":
|
||||
specs = []
|
||||
for key in ("parser", "evaluator", "primitives", "renderer"):
|
||||
filename, title, desc = _SPEC_FILES[key]
|
||||
filepath = os.path.join(ref_dir, filename)
|
||||
source = _read_spec(filepath)
|
||||
specs.append({
|
||||
"title": title,
|
||||
"desc": desc,
|
||||
"filename": filename,
|
||||
"source": source,
|
||||
"href": f"/specs/{key}",
|
||||
})
|
||||
return {**base, "spec-title": "SX Core Specification", "spec-files": specs}
|
||||
|
||||
info = _SPEC_FILES.get(slug)
|
||||
if not info:
|
||||
return {**base, "spec-not-found": True}
|
||||
|
||||
filename, title, desc = info
|
||||
filepath = os.path.join(ref_dir, filename)
|
||||
source = _read_spec(filepath)
|
||||
return {**base,
|
||||
"spec-title": title, "spec-desc": desc,
|
||||
"spec-filename": filename, "spec-source": source}
|
||||
|
||||
|
||||
def _read_spec(filepath: str) -> str:
|
||||
"""Read a spec file, returning empty string if missing."""
|
||||
try:
|
||||
with open(filepath, encoding="utf-8") as f:
|
||||
return f.read()
|
||||
except FileNotFoundError:
|
||||
return ";; spec file not found"
|
||||
|
||||
|
||||
def _attr_detail_data(slug: str) -> dict:
|
||||
"""Return attribute detail data for a specific attribute slug.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user