diff --git a/docs/hero.webp b/docs/hero.webp new file mode 100644 index 0000000..35e5b75 Binary files /dev/null and b/docs/hero.webp differ diff --git a/docs/index.md b/docs/index.md index 05441b8..8803d6e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,11 +1,19 @@ --- title: OXA Schema +site: + hide_outline: true + hide_title_block: true --- -> **A foundation for interoperable, structured scientific content.** -> OXA defines open, extensible JSON schemas that describe modular and composable scientific documents — bridging the gap between authoring systems like **Stencila**, **MyST**, **Quarto** and the scientific publishing ecosystem which uses tools like **JATS**. - -## Overview +:::{hero .col-screen} OXA Documentation +:background-image: hero.webp +:max-width: 100 +:overlay: 60 +:kicker: Open Exchange Architecture +:actions: [Get Started](./install.md) [Schema](./schema-overview.md) +:footer: OXA defines open, extensible JSON schemas that describe modular and composable scientific documents — bridging the gap between authoring systems like Stencila, MyST, Quarto and the scientific publishing ecosystem which uses tools like JATS. +A foundation for interoperable, structured scientific content. +::: The **Open Exchange Architecture (OXA)** is a specification for representing scientific documents and their components as structured JSON objects. It’s designed to enable **exchange, interoperability, and long-term preservation** of scientific knowledge, while remaining compatible with modern web and data standards. diff --git a/docs/install.md b/docs/install.md new file mode 100644 index 0000000..cef4a18 --- /dev/null +++ b/docs/install.md @@ -0,0 +1,189 @@ +--- +title: Get Started +--- + +OXA provides tools and libraries for working with OXA documents in multiple languages. This guide will help you get started quickly. + +## Installation + +### Command Line Tool + +The OXA CLI tool allows you to validate OXA documents from the command line. + +::::{tab-set} +:::{tab-item sync=js} NPM + +```bash +npm install -g oxa +``` + +::: + +:::{tab-item sync=py} Python + +```bash +pip install oxa +``` + +::: +:::: + +## Quick Start + +### Validate a Document + +Once installed, you can validate OXA documents: + +```bash +# Validate a JSON file +oxa validate document.json + +# Validate multiple files +oxa validate *.json + +# Validate from stdin +cat document.json | oxa validate - + +# Validate YAML files +oxa validate document.yaml + +# Validate against a specific node type +oxa validate --type Heading heading.json + +# Quiet mode (only show errors) +oxa validate -q *.json +``` + +### Example Document + +Create a simple OXA document in `example.json`: + +```json +{ + "type": "Document", + "children": [ + { + "type": "Heading", + "level": 1, + "children": [ + { + "type": "Text", + "value": "Hello, OXA!" + } + ] + }, + { + "type": "Paragraph", + "children": [ + { + "type": "Text", + "value": "This is a simple OXA document." + } + ] + } + ] +} +``` + +Validate it: + +```bash +oxa validate example.json +``` + +## Programmatic Libraries + +For programmatic usage in your applications, install the appropriate library for your language: + +::::{tab-set} +:::{tab-item sync=js} JavaScript/TypeScript + +```bash +# Core validation library +npm install @oxa/core + +# TypeScript type definitions +npm install oxa-types +``` + +::: + +:::{tab-item sync=py} Python + +```bash +pip install oxa-types +``` + +::: + +:::{tab-item sync=rs} Rust + +Add to your `Cargo.toml`: + +```toml +[dependencies] +oxa-types = "0.1.0" +``` + +::: +:::: + +### Using the Programmatic API + +::::{tab-set} + +:::{tab-item sync=js} JavaScript/TypeScript + +```typescript +import { validate } from "@oxa/core"; +import type { Document } from "oxa-types"; + +const document: Document = { + type: "Document", + children: [ + { + type: "Paragraph", + children: [{ type: "Text", value: "Hello, world!" }], + }, + ], +}; + +const result = validate(document); +if (result.valid) { + console.log("Document is valid!"); +} else { + console.error("Validation errors:", result.errors); +} +``` + +::: + +:::{tab-item sync=py} Python + +```python +from oxa_types import Document, Paragraph, Text + +document = Document( + children=[ + Paragraph( + children=[ + Text(value="Hello, world!") + ] + ) + ] +) +``` + +::: +:::: + +## Next Steps + +- Learn about the [OXA Schema](./schema.md) structure +- Explore the [Schema Reference](./schema/index.md) for detailed node types +- Check out examples in the [OXA repository](https://github.com/oxa-dev/oxa) + +## Getting Help + +- Join the [Discord community](https://discord.oxa.dev) +- Report issues on [GitHub](https://github.com/oxa-dev/oxa) diff --git a/docs/myst.yml b/docs/myst.yml index 4908df7..a86c0d0 100644 --- a/docs/myst.yml +++ b/docs/myst.yml @@ -11,10 +11,16 @@ project: AST: Abstract Syntax Tree JATS: Journal Article Tag Suite JSON: JavaScript Object Notation + CLI: Command Line Interface + API: Application Programming Interface toc: - file: index.md + - file: install.md + - file: schema-overview.md - title: Schema Reference children: - pattern: schema/*.md site: template: book-theme + options: + folders: true diff --git a/docs/schema-overview.md b/docs/schema-overview.md new file mode 100644 index 0000000..34e55db --- /dev/null +++ b/docs/schema-overview.md @@ -0,0 +1,88 @@ +--- +title: Schema +--- + +# OXA Schema + +The OXA schema defines the structure and types for representing scientific documents as JSON objects. All OXA documents conform to JSON Schema Draft-07, enabling validation and interoperability. + +## Schema Overview + +Every OXA node follows a common structure: + +```yaml +type: NodeType # Required: The node type identifier +id: optional-string # Optional: Unique identifier for referencing +classes: [] # Optional: Styling or semantic classes +data: {} # Optional: Arbitrary metadata +children: [] # Optional: Nested content nodes +``` + +### Common Properties + +| Property | Type | Description | +| ---------- | ---------------------- | --------------------------------------------------------- | +| `type` | `string` (Capitalized) | The node type, e.g. `"Paragraph"`, `"Text"`, `"Heading"`. | +| `id` | `string` | Unique identifier for referencing and linking nodes. | +| `classes` | `array[string]` | Optional styling or semantic classes. | +| `data` | `object` | Arbitrary metadata (e.g. attributes, provenance, DOI). | +| `children` | `array` | Nested content nodes — block or inline types. | + +## Node Types + +OXA defines several categories of node types: + +### Document Node + +The root node of every OXA document: + +- [Document](#oxa:document) — The root container with metadata, title, and block content + +### Block Nodes + +Block-level content that forms the document structure: + +- [Heading](#oxa:heading) — Section headings with levels (1-6) +- [Paragraph](#oxa:paragraph) — Text paragraphs + +### Inline Nodes + +Inline content that appears within block nodes: + +- [Text](#oxa:text) — Plain text content +- [Strong](#oxa:strong) — Strong emphasis (typically bold) + +## Accessing the Schema + +### Download the Schema + +The OXA schema is available as a JSON Schema file: + + + +### Schema Versioning + +OXA uses semantic versioning for schema releases. The current version is **0.1.0**. When accessing schemas programmatically, always specify the version: + +```bash +# Download specific version +curl https://oxa.dev/v0.1.0/schema.json > schema.json +``` + +## Design Principles + +The OXA schema follows these design principles: + +- **Open by design:** JSON Schema–based and CC0-licensed for reuse and extension +- **Composable:** Each node is self-contained, typed, and can be nested or reused +- **Interoperable:** Compatible with MyST Markdown, Stencila, Quarto, and similar formats +- **Extensible:** Add new node types while preserving schema validation +- **Typed & linked:** Everything has a clear `type`, optional `id`, and structured `data` field +- **Modular:** Documents and components can link across projects +- **Computational:** Built-in support for executable and interactive research components + +## Related Resources + +- [Get Started Guide](./install.md) — Installation and quick start +- [Schema Reference](./schema/index.md) — Detailed node type documentation +- [OXA Repository](https://github.com/oxa-dev/oxa) — Source code and examples diff --git a/docs/schema/index.md b/docs/schema/index.md new file mode 100644 index 0000000..ef8525f --- /dev/null +++ b/docs/schema/index.md @@ -0,0 +1,11 @@ +# Schema Reference + +For detailed documentation on each node type, see the [Schema Reference](./schema/index.md): + +- [Document](./schema/document.md) — Root document structure +- [Block Nodes](./schema/block.md) — Block-level content types +- [Inline Nodes](./schema/inline.md) — Inline content types +- [Heading](./schema/heading.md) — Section headings +- [Paragraph](./schema/paragraph.md) — Text paragraphs +- [Text](./schema/text.md) — Plain text nodes +- [Strong](./schema/strong.md) — Strong emphasis diff --git a/scripts/lib/generate-docs.ts b/scripts/lib/generate-docs.ts index 9fe794f..9300aa6 100644 --- a/scripts/lib/generate-docs.ts +++ b/scripts/lib/generate-docs.ts @@ -5,12 +5,13 @@ * directory, formatted for use in documentation sites. */ -import { mkdirSync, rmSync, writeFileSync, existsSync } from "fs"; +import { mkdirSync, rmSync, writeFileSync, existsSync, readFileSync } from "fs"; import { join } from "path"; import { loadMergedSchema } from "./schema.js"; const OUTPUT_DIR = join(import.meta.dirname, "../../docs/schema"); +const INDEX_FILE = join(OUTPUT_DIR, "index.md"); interface SchemaProperty { type?: string; @@ -34,12 +35,23 @@ interface SchemaDefinition { } export async function generateDocs(): Promise { + // Preserve index.md if it exists + let indexContent: string | null = null; + if (existsSync(INDEX_FILE)) { + indexContent = readFileSync(INDEX_FILE, "utf-8"); + } + // Delete and recreate output directory if (existsSync(OUTPUT_DIR)) { rmSync(OUTPUT_DIR, { recursive: true, force: true }); } mkdirSync(OUTPUT_DIR, { recursive: true }); + // Restore index.md if it was preserved + if (indexContent !== null) { + writeFileSync(INDEX_FILE, indexContent); + } + const schema = loadMergedSchema(); const definitions = schema.definitions as Record;