Adding a format
JinnTap ships with two dialects — TEI and JATS — selected by the
format attribute. Supporting another XML dialect means
teaching the editor three things: how to wrap and prefix the document, which
schema JSON to load by default, and how to convert between that dialect’s
XML and the editor’s HTML custom elements.
Use TEI (src/util/module-tei.xq, src/tei-schema.json) and JATS
(src/util/module-jats.xq, src/jats-schema.json) as templates. The checklist below
walks through adding DocBook as a third format (format="docbook"). DocBook is
not built in today — the snippets are illustrative only.
1. Register the format config
Add an entry in
src/util/xml-formats.js
and register it in FORMATS:
export const DOCBOOK_FORMAT = {
namespace: 'http://docbook.org/ns/docbook',
rootElement: 'article',
bodyWrapper: 'article', // fragment wrapper used on export
prefix: 'db-', // HTML custom elements: <db-sect1>, …
notesWrapper: 'bibliography', // or a dedicated notes container in your schema
noteName: 'footnote',
anchorName: 'xref',
linkDirection: 'anchor-to-note', // xref points at footnote (cf. JATS)
newDocumentTemplate: () => `<article xmlns="http://docbook.org/ns/docbook" version="5.0">
<title>Untitled</title>
<section>
<title>Section</title>
<para/>
</section>
</article>`,
};
export const FORMATS = {
tei: TEI_FORMAT,
jats: JATS_FORMAT,
docbook: DOCBOOK_FORMAT,
};
| Field | Role |
|---|---|
namespace |
Written onto the body wrapper on export when non-empty |
prefix |
Prefix for editor custom elements (tei-, jats-, db-, …) |
bodyWrapper |
Element that wraps the editable fragment during export |
notesWrapper / noteName / anchorName |
Footnote plumbing passed into the editor extensions |
linkDirection |
note-to-anchor (note points at anchor) or anchor-to-note (anchor points at note) |
newDocumentTemplate |
Skeleton used when creating an empty document |
getFormat(formatId) must return your config; unknown ids currently fall back to TEI.
Exact note/xref wiring depends on how your dialect links footnotes — tune
noteName, anchorName, and linkDirection to match.
2. Add a built-in schema
- Create
src/docbook-schema.json— same top-level shape assrc/tei-schema.json(css,attributes,toolbar,selects,schema). Element keys are DocBook local names (section,para,emphasis,footnote, …). - Import it in
src/jinn-tap.jsand extendgetDefaultSchema()/updateSchemaForFormat()soformat="docbook"selects it (today those methods only special-casejats).
Hosts can still override the built-in with the
schema attribute; the format still controls prefix and
import/export.
3. Implement the XQuery I/O module
XML round-tripping is done by fontoxpath modules registered in
src/util/xml.js.
Each format needs its own module namespace URI so the correct transform is selected.
-
Create
src/util/module-docbook.xqwith:module namespace jt = 'http://jinntec.de/jinntap/docbook'; declare namespace db = 'http://docbook.org/ns/docbook'; declare function jt:new-document() as node() { … }; declare function jt:import($doc as node()) as node()* { … }; declare function jt:export($nodes as node()*, $input as document-node(), $meta as map(*)) as node()* { … }; -
In
xml.js:import docbookModule from './module-docbook.xq?raw'registerXQueryModule(docbookModule)- extend
getModuleNamespace('docbook')to return that URI (and a distinct XQuery prefix formoduleImports)
Import must turn DocBook XML into HTML custom elements using your prefix
(e.g. <section> → <db-section>, <para> → <db-para>), strip or relocate
non-editable chrome (info, metadata), and place footnotes where the editor expects
them.
Export receives the serialized editor fragment (unprefixed XML local names),
merges it back into the original document ($input), and restores the DocBook
namespace / wrappers.
4. Stylesheet via schema css
Point the schema at a stylesheet with a top-level css property. Paths are
resolved relative to the schema file (or against the library module for built-ins):
{
"css": "./docbook-editor-styles.css",
"attributes": { },
"schema": { }
}
Built-in examples:
src/tei-editor-styles.css—tei-*src/jats-editor-styles.css—jats-*
<jinn-tap> injects the resolved URL as a <link rel="stylesheet">. Add e.g.
src/docbook-editor-styles.css targeting db-*, set "css": "./docbook-editor-styles.css"
in the schema, and ship the CSS next to the schema (the docs site copies package
CSS via scripts/copy-site-assets.js).
5. Smoke-test the pipeline
<jinn-tap format="docbook"></jinn-tap>— empty document fromjt:new-document().- Load a real DocBook sample with
urlor.xml = …— import must producedb-*elements that match your schema. - Edit, then read
.xml— export must restore a valid DocBook document. - Optional: footnotes — verify
notesWrapper/linkDirectionagainst DocBook’sfootnote/xrefmodel.
What you do not need to change
- ProseMirror node/mark type machinery (
createFromSchema) — it already takesprefixand footnote options from the format config. - Serialization of editor → fragment XML (
src/util/serialize.js) — it emits local names; the XQuery export step reattaches dialect structure and namespaces. - Unknown-element synthesis — works for any prefix once
format.prefixis set.