Skip to content

Commit 28d45b2

Browse files
committed
add example and fix some converters
1 parent 19f61a5 commit 28d45b2

File tree

12 files changed

+177
-30
lines changed

12 files changed

+177
-30
lines changed

crates/tyx-schema/src/generated.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,42 @@ impl ::std::default::Default for TyXLength {
11561156
/// }
11571157
/// }
11581158
/// }
1159+
/// },
1160+
/// {
1161+
/// "title": "TyXTabNode",
1162+
/// "description": "A node describing a tab character.",
1163+
/// "type": "object",
1164+
/// "required": [
1165+
/// "text",
1166+
/// "type"
1167+
/// ],
1168+
/// "properties": {
1169+
/// "type": {
1170+
/// "type": "string",
1171+
/// "const": "tab"
1172+
/// },
1173+
/// "text": {
1174+
/// "type": "string"
1175+
/// }
1176+
/// }
1177+
/// },
1178+
/// {
1179+
/// "title": "TyXCodeHighlightNode",
1180+
/// "description": "A node describing highlighted code text.",
1181+
/// "type": "object",
1182+
/// "required": [
1183+
/// "text",
1184+
/// "type"
1185+
/// ],
1186+
/// "properties": {
1187+
/// "type": {
1188+
/// "type": "string",
1189+
/// "const": "code-highlight"
1190+
/// },
1191+
/// "text": {
1192+
/// "type": "string"
1193+
/// }
1194+
/// }
11591195
/// }
11601196
/// ],
11611197
/// "id": "TyXNode"
@@ -1303,6 +1339,16 @@ A function call node.*/
13031339
)]
13041340
position_parameters: ::std::vec::Vec<TyXValue>,
13051341
},
1342+
/**TyXTabNode
1343+
1344+
A node describing a tab character.*/
1345+
#[serde(rename = "tab")]
1346+
Tab { text: ::std::string::String },
1347+
/**TyXCodeHighlightNode
1348+
1349+
A node describing highlighted code text.*/
1350+
#[serde(rename = "code-highlight")]
1351+
CodeHighlight { text: ::std::string::String },
13061352
}
13071353
impl ::std::convert::From<&Self> for TyXNode {
13081354
fn from(value: &TyXNode) -> Self {

crates/tyx-to-typst/src/lib.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,17 +131,20 @@ fn node_to_typst(root: &TyXNode) -> Option<String> {
131131
direction,
132132
..
133133
}
134-
| TyXNode::Quote {
134+
| TyXNode::Tablecell {
135135
children,
136136
direction,
137137
..
138-
}
139-
| TyXNode::Tablecell {
138+
} => Some(apply_direction(
139+
&children_to_typst(children),
140+
direction.clone().unwrap_or(TyXDirection(None)),
141+
)),
142+
TyXNode::Quote {
140143
children,
141144
direction,
142145
..
143146
} => Some(apply_direction(
144-
&children_to_typst(children),
147+
&format!("#quote(block: true)[{}]", children_to_typst(children)),
145148
direction.clone().unwrap_or(TyXDirection(None)),
146149
)),
147150
TyXNode::Paragraph {
@@ -156,6 +159,8 @@ fn node_to_typst(root: &TyXNode) -> Option<String> {
156159
TyXNode::Text { text, format, .. } => {
157160
Some(apply_text_format(typst_escape(text), text, *format))
158161
}
162+
TyXNode::Tab { .. } => Some("\t".into()),
163+
TyXNode::CodeHighlight { text, .. } => Some(typst_escape(text)),
159164
TyXNode::Math { typst, inline, .. } => {
160165
if inline.unwrap_or(false) {
161166
Some(format!("${}$", typst.clone().unwrap_or_default()))
@@ -238,7 +243,7 @@ fn node_to_typst(root: &TyXNode) -> Option<String> {
238243
TyXNode::Tablerow { children, .. } => Some(
239244
children
240245
.iter()
241-
.map(|child| node_to_typst(child).unwrap_or_default())
246+
.map(|child| format!("[{}]", node_to_typst(child).unwrap_or_default()))
242247
.collect::<Vec<String>>()
243248
.join(", "),
244249
),

examples/Showcase.tyx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"$schema":"https://tyx-editor.com/schemas/tyx-document.schema.json","version":"0.2.15","preamble":"","content":{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"This is an example document!","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Headings","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"heading","version":1,"tag":"h1"},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Just Work!","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"heading","version":1,"tag":"h2"},{"children":[{"detail":0,"format":1,"mode":"normal","style":"","text":"Bold","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":" ","type":"text","version":1},{"detail":0,"format":2,"mode":"normal","style":"","text":"Italic","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":" ","type":"text","version":1},{"detail":0,"format":8,"mode":"normal","style":"","text":"Underline","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":" ","type":"text","version":1},{"detail":0,"format":4,"mode":"normal","style":"","text":"Strikethrough","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":" x","type":"text","version":1},{"detail":0,"format":32,"mode":"normal","style":"","text":"2","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":" and x","type":"text","version":1},{"detail":0,"format":64,"mode":"normal","style":"","text":"2","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":" and also ","type":"text","version":1},{"detail":0,"format":16,"mode":"normal","style":"","text":"int main()","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":".","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":1,"textStyle":""},{"children":[{"type":"image","version":1,"src":"../public/icon.png"},{"detail":0,"format":0,"mode":"normal","style":"","text":"This has space here: ","type":"text","version":1},{"type":"functioncall","version":1,"name":"h","inline":true,"positionParameters":[{"unit":"em","value":"1","type":"length"}],"namedParameters":{"weak":{"type":"boolean"}}},{"detail":0,"format":0,"mode":"normal","style":"","text":" does it?","type":"text","version":1},{"type":"functioncall","version":1,"name":"footnote","inline":true,"positionParameters":[{"type":"content","value":{"type":"root","children":[{"type":"paragraph","children":[{"type":"text","text":"technically, it does!","format":0,"detail":0,"mode":"normal","style":"","version":1}],"format":"","direction":null,"indent":0,"version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"version":1}}],"namedParameters":{}},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Let ","type":"text","version":1},{"type":"math","version":1,"inline":true,"formula":"\\varepsilon>0","typst":"epsilon > 0"},{"detail":0,"format":0,"mode":"normal","style":"","text":", then for ","type":"text","version":1},{"type":"math","version":1,"inline":true,"formula":"N:=\\lceil\\frac{1}{\\varepsilon}\\rceil","typst":"N : = ceil(1/epsilon)"},{"detail":0,"format":0,"mode":"normal","style":"","text":" we have for all ","type":"text","version":1},{"type":"math","version":1,"inline":true,"formula":"n>N","typst":"n > N"},{"detail":0,"format":0,"mode":"normal","style":"","text":" that:","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"type":"math","version":1,"inline":false,"formula":"\\left|\\frac{1}{n}\\right|<\\frac{1}{N}<\\varepsilon","typst":"lr(| 1/n |) < 1/N < epsilon"},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"That is very wise.","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"quote","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"type":"horizontalrule","version":1},{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"This","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"listitem","version":1,"value":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Is","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"listitem","version":1,"value":2},{"children":[{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"A bullet","type":"text","version":1}],"direction":null,"format":"","indent":1,"type":"listitem","version":1,"value":1}],"direction":null,"format":"","indent":0,"type":"list","version":1,"listType":"bullet","start":1,"tag":"ul"}],"direction":null,"format":"","indent":0,"type":"listitem","version":1,"value":3},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"List","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"listitem","version":1,"value":3}],"direction":null,"format":"","indent":0,"type":"list","version":1,"listType":"bullet","start":1,"tag":"ul"},{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"and","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"listitem","version":1,"value":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"this","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"listitem","version":1,"value":2},{"children":[{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"is","type":"text","version":1}],"direction":null,"format":"","indent":1,"type":"listitem","version":1,"value":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"numbered","type":"text","version":1}],"direction":null,"format":"","indent":1,"type":"listitem","version":1,"value":2}],"direction":null,"format":"","indent":0,"type":"list","version":1,"listType":"number","start":1,"tag":"ol"}],"direction":null,"format":"","indent":0,"type":"listitem","version":1,"value":3},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"well!","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"listitem","version":1,"value":3}],"direction":null,"format":"","indent":0,"type":"list","version":1,"listType":"number","start":1,"tag":"ol"},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"fn","type":"code-highlight","version":1,"highlightType":"keyword"},{"detail":0,"format":0,"mode":"normal","style":"","text":" ","type":"code-highlight","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":"main","type":"code-highlight","version":1,"highlightType":"function-definition"},{"detail":0,"format":0,"mode":"normal","style":"","text":"(","type":"code-highlight","version":1,"highlightType":"punctuation"},{"detail":0,"format":0,"mode":"normal","style":"","text":")","type":"code-highlight","version":1,"highlightType":"punctuation"},{"detail":0,"format":0,"mode":"normal","style":"","text":" ","type":"code-highlight","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":"{","type":"code-highlight","version":1,"highlightType":"punctuation"},{"type":"linebreak","version":1},{"detail":2,"format":0,"mode":"normal","style":"","text":"\t","type":"tab","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":"let","type":"code-highlight","version":1,"highlightType":"keyword"},{"detail":0,"format":0,"mode":"normal","style":"","text":" ","type":"code-highlight","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":"mut","type":"code-highlight","version":1,"highlightType":"keyword"},{"detail":0,"format":0,"mode":"normal","style":"","text":" x ","type":"code-highlight","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":"=","type":"code-highlight","version":1,"highlightType":"operator"},{"detail":0,"format":0,"mode":"normal","style":"","text":" ","type":"code-highlight","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":"String","type":"code-highlight","version":1,"highlightType":"class-name"},{"detail":0,"format":0,"mode":"normal","style":"","text":"::","type":"code-highlight","version":1,"highlightType":"punctuation"},{"detail":0,"format":0,"mode":"normal","style":"","text":"new","type":"code-highlight","version":1,"highlightType":"function"},{"detail":0,"format":0,"mode":"normal","style":"","text":"(","type":"code-highlight","version":1,"highlightType":"punctuation"},{"detail":0,"format":0,"mode":"normal","style":"","text":")","type":"code-highlight","version":1,"highlightType":"punctuation"},{"detail":0,"format":0,"mode":"normal","style":"","text":";","type":"code-highlight","version":1,"highlightType":"punctuation"},{"type":"linebreak","version":1},{"detail":2,"format":0,"mode":"normal","style":"","text":"\t","type":"tab","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":"x ","type":"code-highlight","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":"+=","type":"code-highlight","version":1,"highlightType":"operator"},{"detail":0,"format":0,"mode":"normal","style":"","text":" ","type":"code-highlight","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":"\"TyX is cool!\"","type":"code-highlight","version":1,"highlightType":"string"},{"detail":0,"format":0,"mode":"normal","style":"","text":";","type":"code-highlight","version":1,"highlightType":"punctuation"},{"type":"linebreak","version":1},{"detail":2,"format":0,"mode":"normal","style":"","text":"\t","type":"tab","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":"println!","type":"code-highlight","version":1,"highlightType":"macro"},{"detail":0,"format":0,"mode":"normal","style":"","text":"(","type":"code-highlight","version":1,"highlightType":"punctuation"},{"detail":0,"format":0,"mode":"normal","style":"","text":"\"{x}\"","type":"code-highlight","version":1,"highlightType":"string"},{"detail":0,"format":0,"mode":"normal","style":"","text":")","type":"code-highlight","version":1,"highlightType":"punctuation"},{"detail":0,"format":0,"mode":"normal","style":"","text":";","type":"code-highlight","version":1,"highlightType":"punctuation"},{"type":"linebreak","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":"}","type":"code-highlight","version":1,"highlightType":"punctuation"}],"direction":null,"format":"","indent":0,"type":"code","version":1,"language":"rust"},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Have a look ","type":"text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"here","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"link","version":1,"rel":"noreferrer","target":null,"title":null,"url":"https://tyx-editor.com"},{"detail":0,"format":0,"mode":"normal","style":"","text":" for more information!","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"children":[{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"This","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Is","type":"text","version":1}],"direction":null,"format":"center","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Cool","type":"text","version":1}],"direction":null,"format":"right","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1}],"direction":null,"format":"","indent":0,"type":"tablerow","version":1}],"direction":null,"format":"","indent":0,"type":"table","version":1},{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Also, a really long paragraph can be justified if you just specify so in the paragraph settings above; This makes paragraphs look really cool and it is actually quite nice. Everything you see is powered by Typst which is a really great project! I’m writing this blob of text just to make sure that justify works!","type":"text","version":1}],"direction":null,"format":"justify","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"root","version":1}},"settings":{"root":"..","fontPaths":[],"language":"en"}}

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
"version": "0.1.0",
55
"type": "module",
66
"scripts": {
7+
"predev": "bun run prebuild",
78
"dev": "vite",
8-
"dev:app": "tauri dev",
9+
"dev:app": "bun run predev && tauri dev",
910
"prebuild": "wasm-pack build crates/tyx-converters-wasm --target web --out-dir ../../src/converters",
1011
"build": "tsc && vite build",
1112
"preview": "vite preview",

python/src/tyx_schema/schema.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# generated by datamodel-codegen:
22
# filename: tyx.schema.json
3-
# timestamp: 2025-12-07T22:51:12+00:00
3+
# timestamp: 2025-12-08T19:59:50+00:00
44

55
from __future__ import annotations
66

@@ -55,6 +55,24 @@ class TyXImageNode(BaseModel):
5555
src: str
5656

5757

58+
class TyXTabNode(BaseModel):
59+
"""
60+
A node describing a tab character.
61+
"""
62+
63+
type: Literal["tab"]
64+
text: str
65+
66+
67+
class TyXCodeHighlightNode(BaseModel):
68+
"""
69+
A node describing highlighted code text.
70+
"""
71+
72+
type: Literal["code-highlight"]
73+
text: str
74+
75+
5876
class TyXDirectionValue(RootModel[str]):
5977
root: str = Field(..., description="Possible direction values of text in TyX.")
6078

@@ -449,6 +467,8 @@ class TyXNode(
449467
"TyXLinkNode",
450468
"TyXHeadingNode",
451469
"TyXFunctionCallNode",
470+
"TyXTabNode",
471+
"TyXCodeHighlightNode",
452472
]
453473
]
454474
):
@@ -471,6 +491,8 @@ class TyXNode(
471491
"TyXLinkNode",
472492
"TyXHeadingNode",
473493
"TyXFunctionCallNode",
494+
"TyXTabNode",
495+
"TyXCodeHighlightNode",
474496
] = Field(..., description="Some TyX node.")
475497

476498

schemas/tyx-document.schema.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,36 @@
502502
}
503503
},
504504
"required": ["type"]
505+
},
506+
{
507+
"description": "A node describing a tab character.",
508+
"title": "TyXTabNode",
509+
"type": "object",
510+
"properties": {
511+
"type": {
512+
"type": "string",
513+
"const": "tab"
514+
},
515+
"text": {
516+
"type": "string"
517+
}
518+
},
519+
"required": ["type", "text"]
520+
},
521+
{
522+
"description": "A node describing highlighted code text.",
523+
"title": "TyXCodeHighlightNode",
524+
"type": "object",
525+
"properties": {
526+
"type": {
527+
"type": "string",
528+
"const": "code-highlight"
529+
},
530+
"text": {
531+
"type": "string"
532+
}
533+
},
534+
"required": ["type", "text"]
505535
}
506536
]
507537
},

schemas/tyx.schema.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,36 @@
515515
}
516516
},
517517
"required": ["type"]
518+
},
519+
{
520+
"description": "A node describing a tab character.",
521+
"title": "TyXTabNode",
522+
"type": "object",
523+
"properties": {
524+
"type": {
525+
"type": "string",
526+
"const": "tab"
527+
},
528+
"text": {
529+
"type": "string"
530+
}
531+
},
532+
"required": ["type", "text"]
533+
},
534+
{
535+
"description": "A node describing highlighted code text.",
536+
"title": "TyXCodeHighlightNode",
537+
"type": "object",
538+
"properties": {
539+
"type": {
540+
"type": "string",
541+
"const": "code-highlight"
542+
},
543+
"text": {
544+
"type": "string"
545+
}
546+
},
547+
"required": ["type", "text"]
518548
}
519549
]
520550
},

0 commit comments

Comments
 (0)