6.3 KiB
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
docsom innehåller en array av block-noder icontent. - 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:
{
"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:
{
"type": "heading",
"attrs": {
"level": 2
},
"content": [
{ "type": "text", "text": "Min Rubrik" }
]
}
AsciiDoc:
Antalet likhetstecken (=) motsvarar värdet i level. Exempel för level: 2:
== 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):
{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Ett vanligt stycke text." }
]
}
AsciiDoc (Vanligt stycke):
Ett vanligt stycke text.
TipTap JSON (Tomt stycke / Tom rad):
{
"type": "paragraph"
}
AsciiDoc (Tomt stycke / Tom rad):
{blank}
4. Code Block (Kodblock)
TipTap JSON:
{
"type": "codeBlock",
"attrs": {
"language": "javascript"
},
"content": [
{ "type": "text", "text": "console.log('Hej');" }
]
}
AsciiDoc:
[source,javascript]
----
console.log('Hej');
----
5. Blockquote (Citatblock)
TipTap JSON:
{
"type": "blockquote",
"content": [
{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Detta är ett citat." }
]
}
]
}
AsciiDoc:
____
Detta är ett citat.
____
6. Horizontal Rule (Avdelare)
TipTap JSON:
{
"type": "horizontalRule"
}
AsciiDoc:
'''
7. Listor (Bullet List / Ordered List)
TipTap JSON (Oordnad / Bullet List):
{
"type": "bulletList",
"content": [
{
"type": "listItem",
"content": [
{
"type": "paragraph",
"content": [{ "type": "text", "text": "Punkt 1" }]
}
]
}
]
}
AsciiDoc (Oordnad):
* Punkt 1
TipTap JSON (Ordnad / Ordered List):
Samma men type är "orderedList".
AsciiDoc (Ordnad):
. Punkt 1
. Punkt 2
.. Underpunkt 2.1
Inline-formatering (Marks)
Hard Break
TipTap JSON:
{ "type": "hardBreak" }
AsciiDoc:
+
Bold
TipTap JSON:
{ "type": "text", "text": "viktig", "marks": [{ "type": "bold" }] }
AsciiDoc:
*viktig*
Italic
TipTap JSON:
{ "type": "text", "text": "speciell", "marks": [{ "type": "italic" }] }
AsciiDoc:
_speciell_
Strike
TipTap JSON:
{ "type": "text", "text": "gammal", "marks": [{ "type": "strike" }] }
AsciiDoc:
[line-through]#gammal#
Code
TipTap JSON:
{ "type": "text", "text": "const x = 1;", "marks": [{ "type": "code" }] }
AsciiDoc:
`const x = 1;`
Link
TipTap JSON:
{ "type": "text", "text": "Klicka här", "marks": [{ "type": "link", "attrs": { "href": "https://example.com" } }] }
AsciiDoc:
https://example.com[Klicka här]
8. Länkar (Links)
Explicita attributslänkar i AsciiDoc.
TipTap JSON:
{
"type": "text",
"text": "platsöversikten",
"marks": [
{
"type": "link",
"attrs": {
"href": "index"
}
}
]
}
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:
{
"type": "admonition",
"attrs": {
"type": "tip"
},
"content": [
{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Spelarna känner till detta..." }
]
}
]
}
AsciiDoc (Förenklad ettklyftig admonition):
[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:
{
"type": "codeBlock",
"attrs": {
"language": "yaml"
},
"content": [
{ "type": "text", "text": "services:\n archivum:" }
]
}
AsciiDoc:
[source,yaml]
----
services:
archivum:
----