Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Overview

RDFa-Editor is a prototype XHTML+RDFa authoring tool using client-side XSLT. Content lives in a `#content` container of structured blocks (p, h1–h3, ul/ol, blockquote, pre, figure, table), always editable Notion-style: typing within blocks, Enter splits, Backspace-at-start merges, toolbar for block types / inline formatting / lists / figures / tables / links, drag-handle reordering (nested blocks included — every `%block` drags, drops land wherever the content model admits it), a `/` slash menu (in an empty block) and markdown shortcuts (`# `, `- `, `1. `, `> `, ` ``` `) that insert/convert blocks per the content model. Nesting follows the **XHTML Strict content model** (see content-model.xsl below): `blockquote` is a block *container* (`blockquote > p+` — bare text inside it is invalid and gets normalized; the toolbar quote toggle wraps/unwraps), `li`/`td`/`th`/`dd`/`figcaption` are `%Flow;` (mixed text AND nested blocks — Tab/Shift+Tab indent/outdent nested lists), `p`/`h1–h6`/`caption`/`dt` are inline-only. Tables are composite blocks (structure locked; `td`/`th`/`caption` editable) inserted via a rows×cols dialog with an optional header row and caption; row/column toolbar controls, Tab/Shift+Tab cell traversal and Enter (step down a column) all grow the grid at its bottom edge. Right-click a text selection to annotate it with RDFa; right-click an existing annotation to edit or remove it. "Extract RDF" shows the page's triples; "Source" shows the canonical XHTML+RDFa serialization (all editing ephemera stripped).
RDFa-Editor is a prototype XHTML+RDFa authoring tool using client-side XSLT. Content lives in a `#content` container of structured blocks (p, h1–h3, ul/ol, blockquote, pre, figure, table), always editable Notion-style: typing within blocks, Enter splits, Backspace-at-start merges, toolbar for block types / inline formatting / lists / figures / tables / links, drag-handle reordering (nested blocks included — every `%block` drags, drops land wherever the content model admits it), a `/` slash menu (in an empty block) and markdown shortcuts (`# `, `- `, `1. `, `> `, ` ``` `) that insert/convert blocks per the content model. Nesting follows the **XHTML Strict content model** (see content-model.xsl below): `blockquote` is a block *container* (`blockquote > p+` — bare text inside it is invalid and gets normalized; the toolbar quote toggle wraps/unwraps), `li`/`td`/`th`/`dd`/`figcaption` are `%Flow;` (mixed text AND nested blocks — Tab/Shift+Tab indent/outdent nested lists), `p`/`h1–h6`/`caption`/`dt` are inline-only. Tables are composite blocks (structure locked; `td`/`th`/`caption` editable) inserted via a rows×cols dialog with an optional header row and caption; row/column toolbar controls, Tab/Shift+Tab cell traversal and Enter (step down a column) all grow the grid at its bottom edge. Right-click a text selection to annotate it with RDFa; right-click an existing annotation to edit or remove it. "Extract RDF" shows the page's triples; "Source" shows the canonical XHTML+RDFa serialization (all editing ephemera stripped) in [Exclusive XML Canonicalization](https://www.w3.org/TR/xml-exc-c14n/) form (`<br></br>`, sorted attributes/namespace declarations, no indentation — the `rdf:XMLLiteral` value space).

## Architecture

XSLT 3.0 running on **SaxonJS 3** with its interactive extensions (`ixsl:` namespace). `index.html` loads `lib/SaxonJS3.js` and executes `dist/index.xsl.sef.json` (initial template `main`). The editor UI is fully generated by the stylesheet — the overlay is rendered once at startup (hidden) and only populated/shown/hidden afterwards, so the stylesheet is self-contained and embeddable on any host page.
XSLT 3.0 running on **SaxonJS 3** with its interactive extensions (`ixsl:` namespace). `index.html` loads `lib/SaxonJS3.js` plus `lib/xml-c14n-sync.js` (the exclusive-c14n serializer LinkedDataHub also ships — the "Source" view calls it through `local:canonicalize-xml` in edit.xsl, a port of LDH's `ldh:canonicalize-xml`: `serialize()` → `parse-xml()` bridges XDM to browser DOM, which the lib walks) and executes `dist/index.xsl.sef.json` (initial template `main`). The editor UI is fully generated by the stylesheet — the overlay is rendered once at startup (hidden) and only populated/shown/hidden afterwards, so the stylesheet is self-contained and embeddable on any host page (host pages must include both libs).

Modules under `src/`:

Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ RDFa extraction and the document canonicalization are all XSLT.
vocabulary dropdowns fed by plain ontology RDF/XML files); right-click an annotation
to edit or remove it.
- **Strictly W3C-conformant RDFa 1.1 extraction** to RDF/XML ("Extract RDF"), a
**canonical serialization** stripping all editing ephemera ("Source"), and
**canonical serialization** stripping all editing ephemera and emitting
[Exclusive XML Canonicalization](https://www.w3.org/TR/xml-exc-c14n/) — the
`rdf:XMLLiteral` value space ("Source"), and
**RDFa lint** (unresolvable terms, unsafe markup, step-11 conflicts) surfaced as
wavy underlines + a breadcrumb badge.
- **Navigation**: ToC drawer (outline with section drag-reorder), breadcrumb bar with
Expand Down Expand Up @@ -47,8 +49,10 @@ See `CLAUDE.md` for the module map and conventions. The load-bearing pieces:
`src/canonical-xhtml.xsl` (canonical + sanitized serialization form, pure XSLT),
`src/lint-rdfa.xsl` (pure), and the IXSL modules `edit.xsl` / `annotate.xsl` /
`overlay.xsl` / `navigate.xsl` / `undo.xsl` / `vocab.xsl`. The editor's stylesheet is
self-contained: a host page provides one or more `.rdfa-editor-content` regions, `rdfa-editor.css`, and
preloads the vocabulary documents into the SaxonJS document pool (see `index.html`).
self-contained: a host page provides one or more `.rdfa-editor-content` regions, `rdfa-editor.css`,
loads `lib/xml-c14n-sync.js` (the exclusive-c14n serializer the "Source" view uses — the same lib
LinkedDataHub canonicalizes `rdf:XMLLiteral`s with), and preloads the vocabulary documents into the
SaxonJS document pool (see `index.html`).

## Embedding in LinkedDataHub

Expand Down
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700" type="text/css">
<title>RDFa Editor</title>
<script type="text/javascript" src="lib/SaxonJS3.js"></script>
<script type="text/javascript" src="lib/xml-c14n-sync.js"></script>
<script type="text/javascript">
window.onload = function() {
// preload the vocabulary documents into the SaxonJS document pool,
Expand Down
1 change: 1 addition & 0 deletions lib/xml-c14n-sync.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions src/canonical-xhtml.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ version="3.0">
RDFa attributes and pre whitespace are never touched; text is never reflowed.
-->

<!-- serialization is the caller's job (view-source serialize(), test -o output);
no xsl:output here - it would conflict with the including stylesheet's -->
<!-- serialization is the caller's job (view-source runs exclusive XML c14n via
local:canonicalize-xml in edit.xsl, tests use -o output); no xsl:output
here - it would conflict with the including stylesheet's -->
<xsl:mode name="canonical" on-no-match="shallow-copy"/>
<xsl:mode name="cm-normalize" on-no-match="shallow-copy"/>

Expand Down
12 changes: 11 additions & 1 deletion src/edit.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -2465,6 +2465,16 @@ version="3.0">

<!-- ................................ view source ................................ -->

<!-- W3C Exclusive XML Canonicalization (the rdf:XMLLiteral value space) via the
xml-c14n lib on the host page - LinkedDataHub's ldh:canonicalize-xml ported.
parse-xml() is the XDM->DOM bridge: the lib walks browser DOM nodes, not
Saxon's temporary trees -->
<xsl:function name="local:canonicalize-xml" as="xs:string">
<xsl:param name="doc" as="document-node()"/>
<xsl:variable name="js-function" select="ixsl:eval('(function (doc) { return window[''xml-c14n-sync.js'']().createCanonicaliser(''http://www.w3.org/2001/10/xml-exc-c14n#WithComments'').canonicaliseSync(doc.documentElement); })')"/>
<xsl:sequence select="ixsl:call($js-function, 'call', [ (), $doc ])"/>
</xsl:function>

<xsl:template match="button[@id = 'view-source']" mode="ixsl:onclick">
<xsl:variable name="canonical" as="element()?">
<xsl:call-template name="canonical-xhtml">
Expand All @@ -2473,7 +2483,7 @@ version="3.0">
</xsl:variable>
<xsl:call-template name="local:show-output">
<xsl:with-param name="title" select="'Canonical XHTML+RDFa'"/>
<xsl:with-param name="text" select="serialize($canonical, map{ 'method': 'xml', 'indent': true() })"/>
<xsl:with-param name="text" select="local:canonicalize-xml(parse-xml(serialize($canonical, map{ 'method': 'xml' })))"/>
</xsl:call-template>
</xsl:template>

Expand Down
1 change: 1 addition & 0 deletions tests/fixture-dragnest.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>RDFa Editor - nested drag-and-drop fixture</title>
<script type="text/javascript" src="../lib/SaxonJS3.js"></script>
<script type="text/javascript" src="../lib/xml-c14n-sync.js"></script>
<script type="text/javascript">
window.onload = function() {
const vocabs = ["vocabs/foaf.rdf", "vocabs/dcterms.rdf"];
Expand Down
1 change: 1 addition & 0 deletions tests/fixture-nesting.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>RDFa Editor - nesting fixture</title>
<script type="text/javascript" src="../lib/SaxonJS3.js"></script>
<script type="text/javascript" src="../lib/xml-c14n-sync.js"></script>
<script type="text/javascript">
window.onload = function() {
const vocabs = ["vocabs/foaf.rdf", "vocabs/dcterms.rdf"];
Expand Down
1 change: 1 addition & 0 deletions tests/fixture.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700" type="text/css">
<title>RDFa Editor</title>
<script type="text/javascript" src="../lib/SaxonJS3.js"></script>
<script type="text/javascript" src="../lib/xml-c14n-sync.js"></script>
<script type="text/javascript">
window.onload = function() {
// preload the vocabulary documents into the SaxonJS document pool,
Expand Down
Loading