Files
Archivum/ASCIIDOC_TIPTAP_CONVERSION.md

352 lines
6.3 KiB
Markdown

# Konvertering mellan AsciiDoc och TipTap: Typspecifikation
Detta dokument beskriver i detalj hur datamodellen mappas mellan **TipTap JSON** och **AsciiDoc**. Dokumentet fungerar som en specifikation för utvecklare som ska implementera konverteringslogik, baserat på referenslogiken från `tiptap-to-asciidoc`.
**Gällande versioner:**
* **TipTap:** v2
* **AsciiDoc:** Asciidoctor (Asciidoctor.js / källkodsstandard)
---
## Översikt av datamodeller
* **TipTap JSON:** Ett träd av _Nodes_ (blockelement som stycken, rubriker, listor) och _Marks_ (inline-formatering som fetstil, kursivt, länkar). Roten i trädet är en nod av typen `doc` som innehåller en array av block-noder i `content`.
* **AsciiDoc:** Textbaserad markup som förlitar sig på radbrytningar och prefix/suffix (t.ex. `==`, `*`, `_`).
Vid konvertering från TipTap till AsciiDoc traverseras JSON-trädet uppifrån och ner.
Vid konvertering från AsciiDoc till TipTap behöver AsciiDoc-mjukvara generellt konvertera texten till HTML, varefter TipTaps inbyggda parser (`@tiptap/html` -> `generateJSON`) nyttjas för att omvandla HTML till TipTap JSON.
---
## Block-noder (Nodes)
### 1. Document (Rot-nod)
**TipTap JSON:**
```json
{
"type": "doc",
"content": [
... // Andra block-noder
]
}
```
**AsciiDoc:**
Inget specifikt syntax, detta representerar hela dokumentfilen. Block-noderna under `content` renderas sekventiellt separerade med tomma rader (två radbrytningar `\n\n` mellan blockelement rekommenderas generellt).
---
### 2. Heading (Rubriker)
Rubriknivåer definieras med attributet `level`.
**TipTap JSON:**
```json
{
"type": "heading",
"attrs": {
"level": 2
},
"content": [
{ "type": "text", "text": "Min Rubrik" }
]
}
```
**AsciiDoc:**
Antalet likhetstecken (`=`) motsvarar värdet i `level`. Exempel för `level: 2`:
```asciidoc
== Min Rubrik
```
---
### 3. Paragraph (Stycken och Tomma rader)
Ett stycke översätts normalt rätt upp och ner. En tom rad i TipTap (ett tomt stycke) representeras via AsciiDocs specialattribut `{blank}` vilket skapar en tom paragraf som parsas tillbaka som ett tomt stycke.
**TipTap JSON (Vanligt stycke):**
```json
{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Ett vanligt stycke text." }
]
}
```
**AsciiDoc (Vanligt stycke):**
```asciidoc
Ett vanligt stycke text.
```
**TipTap JSON (Tomt stycke / Tom rad):**
```json
{
"type": "paragraph"
}
```
**AsciiDoc (Tomt stycke / Tom rad):**
```asciidoc
{blank}
```
---
### 4. Code Block (Kodblock)
**TipTap JSON:**
```json
{
"type": "codeBlock",
"attrs": {
"language": "javascript"
},
"content": [
{ "type": "text", "text": "console.log('Hej');" }
]
}
```
**AsciiDoc:**
```asciidoc
[source,javascript]
----
console.log('Hej');
----
```
---
### 5. Blockquote (Citatblock)
**TipTap JSON:**
```json
{
"type": "blockquote",
"content": [
{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Detta är ett citat." }
]
}
]
}
```
**AsciiDoc:**
```asciidoc
____
Detta är ett citat.
____
```
---
### 6. Horizontal Rule (Avdelare)
**TipTap JSON:**
```json
{
"type": "horizontalRule"
}
```
**AsciiDoc:**
```asciidoc
'''
```
---
### 7. Listor (Bullet List / Ordered List)
**TipTap JSON (Oordnad / Bullet List):**
```json
{
"type": "bulletList",
"content": [
{
"type": "listItem",
"content": [
{
"type": "paragraph",
"content": [{ "type": "text", "text": "Punkt 1" }]
}
]
}
]
}
```
**AsciiDoc (Oordnad):**
```asciidoc
* Punkt 1
```
**TipTap JSON (Ordnad / Ordered List):**
Samma men `type` är `"orderedList"`.
**AsciiDoc (Ordnad):**
```asciidoc
. Punkt 1
. Punkt 2
.. Underpunkt 2.1
```
---
## Inline-formatering (Marks)
### Hard Break
**TipTap JSON:**
```json
{ "type": "hardBreak" }
```
**AsciiDoc:**
```asciidoc
+
```
### Bold
**TipTap JSON:**
```json
{ "type": "text", "text": "viktig", "marks": [{ "type": "bold" }] }
```
**AsciiDoc:**
```asciidoc
*viktig*
```
### Italic
**TipTap JSON:**
```json
{ "type": "text", "text": "speciell", "marks": [{ "type": "italic" }] }
```
**AsciiDoc:**
```asciidoc
_speciell_
```
### Strike
**TipTap JSON:**
```json
{ "type": "text", "text": "gammal", "marks": [{ "type": "strike" }] }
```
**AsciiDoc:**
```asciidoc
[line-through]#gammal#
```
### Code
**TipTap JSON:**
```json
{ "type": "text", "text": "const x = 1;", "marks": [{ "type": "code" }] }
```
**AsciiDoc:**
```asciidoc
`const x = 1;`
```
### Link
**TipTap JSON:**
```json
{ "type": "text", "text": "Klicka här", "marks": [{ "type": "link", "attrs": { "href": "https://example.com" } }] }
```
**AsciiDoc:**
```asciidoc
https://example.com[Klicka här]
```
---
### 8. Länkar (Links)
Explicita attributslänkar i AsciiDoc.
**TipTap JSON:**
```json
{
"type": "text",
"text": "platsöversikten",
"marks": [
{
"type": "link",
"attrs": {
"href": "index"
}
}
]
}
```
**AsciiDoc:**
```asciidoc
link:index[platsöversikten]
```
*(Notera att http/https-länkar kan använda `https://exempel.com[text]`, medan interna/släktlänkar primärt använder `link:path[text]` i AsciiDoc).*
---
### 9. Admonitions (Varningar, Tips, Notiser)
Informationsblock som sticker ut från mängden. För att TipTap inte ska tappa bort detta (vilket ofta sker om man låter standard HTML-tabeller importeras), representeras detta som en egen anpassad (custom) nod-typ i JSON, `admonition`.
**TipTap JSON:**
```json
{
"type": "admonition",
"attrs": {
"type": "tip"
},
"content": [
{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Spelarna känner till detta..." }
]
}
]
}
```
**AsciiDoc (Förenklad ettklyftig admonition):**
```asciidoc
[TIP]
====
Spelarna känner till detta...
====
```
*(Eller enraders som `TIP: Spelarna...` - men blockformat är mer robust och generikt).*
---
### 10. Code Block - Språk-attribut (Syntax Highlighting)
För att kodblocket ska förstå och färgkoda språket korrekt (till exempel `yaml`), paraserar koden `attrs.language` i TipTap JSON med `language` till `source`-parametern i AsciiDoc.
**TipTap JSON:**
```json
{
"type": "codeBlock",
"attrs": {
"language": "yaml"
},
"content": [
{ "type": "text", "text": "services:\n archivum:" }
]
}
```
**AsciiDoc:**
```asciidoc
[source,yaml]
----
services:
archivum:
----
```