2023-01-13 05:40:33 +01:00
|
|
|
import { defineComponent, h } from "vue";
|
|
|
|
import * as mfm from "mfm-js";
|
|
|
|
import type { VNode } from "vue";
|
|
|
|
import MkUrl from "@/components/global/MkUrl.vue";
|
|
|
|
import MkLink from "@/components/MkLink.vue";
|
|
|
|
import MkMention from "@/components/MkMention.vue";
|
|
|
|
import MkEmoji from "@/components/global/MkEmoji.vue";
|
|
|
|
import { concat } from "@/scripts/array";
|
|
|
|
import MkFormula from "@/components/MkFormula.vue";
|
|
|
|
import MkCode from "@/components/MkCode.vue";
|
|
|
|
import MkGoogle from "@/components/MkGoogle.vue";
|
|
|
|
import MkSparkle from "@/components/MkSparkle.vue";
|
|
|
|
import MkA from "@/components/global/MkA.vue";
|
|
|
|
import { host } from "@/config";
|
|
|
|
import { reducedMotion } from "@/scripts/reduced-motion";
|
2023-04-07 07:28:44 +02:00
|
|
|
import { defaultStore } from "@/store";
|
2018-03-31 14:41:08 +02:00
|
|
|
|
2020-10-17 13:12:00 +02:00
|
|
|
export default defineComponent({
|
2018-03-31 14:41:08 +02:00
|
|
|
props: {
|
|
|
|
text: {
|
|
|
|
type: String,
|
2022-06-23 14:46:15 +02:00
|
|
|
required: true,
|
2018-03-31 14:41:08 +02:00
|
|
|
},
|
2019-07-05 17:46:00 +02:00
|
|
|
plain: {
|
2018-03-31 14:41:08 +02:00
|
|
|
type: Boolean,
|
2022-06-23 14:46:15 +02:00
|
|
|
default: false,
|
2018-03-31 14:41:08 +02:00
|
|
|
},
|
2019-07-05 17:46:00 +02:00
|
|
|
nowrap: {
|
2018-12-06 02:02:04 +01:00
|
|
|
type: Boolean,
|
2022-06-23 14:46:15 +02:00
|
|
|
default: false,
|
2018-12-06 02:02:04 +01:00
|
|
|
},
|
2018-11-20 21:11:00 +01:00
|
|
|
author: {
|
|
|
|
type: Object,
|
2022-06-23 14:46:15 +02:00
|
|
|
default: null,
|
2018-11-20 21:11:00 +01:00
|
|
|
},
|
2018-03-31 14:41:08 +02:00
|
|
|
i: {
|
|
|
|
type: Object,
|
2022-06-23 14:46:15 +02:00
|
|
|
default: null,
|
2018-11-02 00:59:40 +01:00
|
|
|
},
|
|
|
|
customEmojis: {
|
|
|
|
required: false,
|
2019-02-17 15:41:47 +01:00
|
|
|
},
|
|
|
|
isNote: {
|
|
|
|
type: Boolean,
|
2022-06-23 14:46:15 +02:00
|
|
|
default: true,
|
2019-02-17 15:41:47 +01:00
|
|
|
},
|
2018-03-31 14:41:08 +02:00
|
|
|
},
|
|
|
|
|
2020-10-17 13:12:00 +02:00
|
|
|
render() {
|
2023-01-13 05:40:33 +01:00
|
|
|
if (this.text == null || this.text === "") return;
|
2018-11-20 21:11:00 +01:00
|
|
|
|
2023-04-10 07:42:17 +02:00
|
|
|
const isPlain = this.plain;
|
|
|
|
|
2023-04-13 02:33:53 +02:00
|
|
|
const ast = (isPlain ? mfm.parseSimple : mfm.parse)(this.text);
|
2018-03-31 14:41:08 +02:00
|
|
|
|
2021-01-03 04:51:50 +01:00
|
|
|
const validTime = (t: string | null | undefined) => {
|
|
|
|
if (t == null) return null;
|
|
|
|
return t.match(/^[0-9.]+s$/) ? t : null;
|
|
|
|
};
|
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
const genEl = (ast: mfm.MfmNode[]) =>
|
|
|
|
concat(
|
2023-04-10 07:42:17 +02:00
|
|
|
ast.map((token, index): VNode[] => {
|
2023-01-13 05:40:33 +01:00
|
|
|
switch (token.type) {
|
|
|
|
case "text": {
|
|
|
|
const text = token.props.text.replace(/(\r\n|\n|\r)/g, "\n");
|
2018-03-31 14:41:08 +02:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
if (!this.plain) {
|
|
|
|
const res = [];
|
|
|
|
for (const t of text.split("\n")) {
|
|
|
|
res.push(h("br"));
|
|
|
|
res.push(t);
|
|
|
|
}
|
|
|
|
res.shift();
|
|
|
|
return res;
|
|
|
|
} else {
|
|
|
|
return [text.replace(/\n/g, " ")];
|
|
|
|
}
|
2021-04-15 05:37:58 +02:00
|
|
|
}
|
2018-08-03 16:27:37 +02:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
case "bold": {
|
|
|
|
return [h("b", genEl(token.children))];
|
2020-11-07 15:41:21 +01:00
|
|
|
}
|
2023-01-13 05:40:33 +01:00
|
|
|
|
|
|
|
case "strike": {
|
|
|
|
return [h("del", genEl(token.children))];
|
2020-11-08 09:08:51 +01:00
|
|
|
}
|
2023-01-13 05:40:33 +01:00
|
|
|
|
|
|
|
case "italic": {
|
|
|
|
return h(
|
|
|
|
"i",
|
|
|
|
{
|
|
|
|
style: "font-style: oblique;",
|
|
|
|
},
|
|
|
|
genEl(token.children),
|
|
|
|
);
|
2022-11-30 03:40:12 +01:00
|
|
|
}
|
2023-01-13 05:40:33 +01:00
|
|
|
|
|
|
|
case "fn": {
|
|
|
|
// TODO: CSSを文字列で組み立てていくと token.props.args.~~~ 経由でCSSインジェクションできるのでよしなにやる
|
|
|
|
let style;
|
|
|
|
switch (token.props.name) {
|
|
|
|
case "tada": {
|
|
|
|
const speed = validTime(token.props.args.speed) || "1s";
|
2023-01-16 20:19:20 +01:00
|
|
|
style = `font-size: 150%;${
|
2023-04-07 07:28:44 +02:00
|
|
|
defaultStore.state.animatedMfm
|
2023-01-13 05:40:33 +01:00
|
|
|
? `animation: tada ${speed} linear infinite both;`
|
2023-01-16 20:19:20 +01:00
|
|
|
: ""
|
|
|
|
}`;
|
2023-01-13 05:40:33 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "jelly": {
|
|
|
|
const speed = validTime(token.props.args.speed) || "1s";
|
|
|
|
style =
|
2023-04-07 07:28:44 +02:00
|
|
|
defaultStore.state.animatedMfm && !reducedMotion()
|
2023-01-13 05:40:33 +01:00
|
|
|
? `animation: mfm-rubberBand ${speed} linear infinite both;`
|
|
|
|
: "";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "twitch": {
|
|
|
|
const speed = validTime(token.props.args.speed) || "0.5s";
|
|
|
|
style =
|
2023-04-07 07:28:44 +02:00
|
|
|
defaultStore.state.animatedMfm && !reducedMotion()
|
2023-01-13 05:40:33 +01:00
|
|
|
? `animation: mfm-twitch ${speed} ease infinite;`
|
|
|
|
: "";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "shake": {
|
|
|
|
const speed = validTime(token.props.args.speed) || "0.5s";
|
|
|
|
style =
|
2023-04-07 07:28:44 +02:00
|
|
|
defaultStore.state.animatedMfm && !reducedMotion()
|
2023-01-13 05:40:33 +01:00
|
|
|
? `animation: mfm-shake ${speed} ease infinite;`
|
|
|
|
: "";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "spin": {
|
|
|
|
const direction = token.props.args.left
|
|
|
|
? "reverse"
|
|
|
|
: token.props.args.alternate
|
|
|
|
? "alternate"
|
|
|
|
: "normal";
|
|
|
|
const anime = token.props.args.x
|
|
|
|
? "mfm-spinX"
|
|
|
|
: token.props.args.y
|
|
|
|
? "mfm-spinY"
|
|
|
|
: "mfm-spin";
|
|
|
|
const speed = validTime(token.props.args.speed) || "1.5s";
|
|
|
|
style =
|
2023-04-07 07:28:44 +02:00
|
|
|
defaultStore.state.animatedMfm && !reducedMotion()
|
2023-01-13 05:40:33 +01:00
|
|
|
? `animation: ${anime} ${speed} linear infinite; animation-direction: ${direction};`
|
|
|
|
: "";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "jump": {
|
|
|
|
const speed = validTime(token.props.args.speed) || "0.75s";
|
|
|
|
style =
|
2023-04-07 07:28:44 +02:00
|
|
|
defaultStore.state.animatedMfm && !reducedMotion()
|
2023-01-13 05:40:33 +01:00
|
|
|
? `animation: mfm-jump ${speed} linear infinite;`
|
|
|
|
: "";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "bounce": {
|
|
|
|
const speed = validTime(token.props.args.speed) || "0.75s";
|
|
|
|
style =
|
2023-04-07 07:28:44 +02:00
|
|
|
defaultStore.state.animatedMfm && !reducedMotion()
|
2023-01-13 05:40:33 +01:00
|
|
|
? `animation: mfm-bounce ${speed} linear infinite; transform-origin: center bottom;`
|
|
|
|
: "";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "rainbow": {
|
|
|
|
const speed = validTime(token.props.args.speed) || "1s";
|
|
|
|
style =
|
2023-04-07 07:28:44 +02:00
|
|
|
defaultStore.state.animatedMfm && !reducedMotion()
|
2023-01-13 05:40:33 +01:00
|
|
|
? `animation: mfm-rainbow ${speed} linear infinite;`
|
|
|
|
: "";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "sparkle": {
|
2023-04-07 07:28:44 +02:00
|
|
|
if (!(defaultStore.state.animatedMfm || reducedMotion())) {
|
2023-01-13 05:40:33 +01:00
|
|
|
return genEl(token.children);
|
|
|
|
}
|
|
|
|
return h(MkSparkle, {}, genEl(token.children));
|
|
|
|
}
|
|
|
|
case "flip": {
|
|
|
|
const transform =
|
|
|
|
token.props.args.h && token.props.args.v
|
|
|
|
? "scale(-1, -1)"
|
|
|
|
: token.props.args.v
|
|
|
|
? "scaleY(-1)"
|
|
|
|
: "scaleX(-1)";
|
|
|
|
style = `transform: ${transform};`;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "x2": {
|
|
|
|
return h(
|
|
|
|
"span",
|
|
|
|
{
|
|
|
|
class: "mfm-x2",
|
|
|
|
},
|
|
|
|
genEl(token.children),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
case "x3": {
|
|
|
|
return h(
|
|
|
|
"span",
|
|
|
|
{
|
|
|
|
class: "mfm-x3",
|
|
|
|
},
|
|
|
|
genEl(token.children),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
case "x4": {
|
|
|
|
return h(
|
|
|
|
"span",
|
|
|
|
{
|
|
|
|
class: "mfm-x4",
|
|
|
|
},
|
|
|
|
genEl(token.children),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
case "font": {
|
|
|
|
const family = token.props.args.serif
|
|
|
|
? "serif"
|
|
|
|
: token.props.args.monospace
|
|
|
|
? "monospace"
|
|
|
|
: token.props.args.cursive
|
|
|
|
? "cursive"
|
|
|
|
: token.props.args.fantasy
|
|
|
|
? "fantasy"
|
|
|
|
: token.props.args.emoji
|
|
|
|
? "emoji"
|
|
|
|
: token.props.args.math
|
|
|
|
? "math"
|
|
|
|
: null;
|
|
|
|
if (family) style = `font-family: ${family};`;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "blur": {
|
|
|
|
return h(
|
|
|
|
"span",
|
|
|
|
{
|
2023-04-07 07:28:44 +02:00
|
|
|
class: "_blur_text",
|
2023-01-13 05:40:33 +01:00
|
|
|
},
|
|
|
|
genEl(token.children),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
case "rotate": {
|
|
|
|
const rotate = token.props.args.x
|
|
|
|
? "perspective(128px) rotateX"
|
|
|
|
: token.props.args.y
|
|
|
|
? "perspective(128px) rotateY"
|
|
|
|
: "rotate";
|
|
|
|
const degrees = parseInt(token.props.args.deg) || "90";
|
|
|
|
style = `transform: ${rotate}(${degrees}deg); transform-origin: center center;`;
|
|
|
|
break;
|
|
|
|
}
|
2023-02-13 05:25:23 +01:00
|
|
|
case "position": {
|
|
|
|
const x = parseFloat(token.props.args.x ?? "0");
|
|
|
|
const y = parseFloat(token.props.args.y ?? "0");
|
|
|
|
style = `transform: translateX(${x}em) translateY(${y}em);`;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "scale": {
|
|
|
|
const x = Math.min(parseFloat(token.props.args.x ?? "1"), 5);
|
|
|
|
const y = Math.min(parseFloat(token.props.args.y ?? "1"), 5);
|
|
|
|
style = `transform: scale(${x}, ${y});`;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "fg": {
|
|
|
|
let color = token.props.args.color;
|
|
|
|
if (!/^[0-9a-f]{3,6}$/i.test(color)) color = "f00";
|
|
|
|
style = `color: #${color};`;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "bg": {
|
|
|
|
let color = token.props.args.color;
|
|
|
|
if (!/^[0-9a-f]{3,6}$/i.test(color)) color = "f00";
|
|
|
|
style = `background-color: #${color};`;
|
|
|
|
break;
|
|
|
|
}
|
2023-01-13 05:40:33 +01:00
|
|
|
}
|
|
|
|
if (style == null) {
|
|
|
|
return h("span", {}, [
|
|
|
|
"$[",
|
|
|
|
token.props.name,
|
|
|
|
" ",
|
|
|
|
...genEl(token.children),
|
|
|
|
"]",
|
|
|
|
]);
|
|
|
|
} else {
|
|
|
|
return h(
|
|
|
|
"span",
|
|
|
|
{
|
|
|
|
style: `display: inline-block;${style}`,
|
|
|
|
},
|
|
|
|
genEl(token.children),
|
|
|
|
);
|
2022-11-30 03:40:12 +01:00
|
|
|
}
|
2021-11-26 05:39:57 +01:00
|
|
|
}
|
2018-03-31 14:41:08 +02:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
case "small": {
|
|
|
|
return [
|
|
|
|
h(
|
|
|
|
"small",
|
|
|
|
{
|
|
|
|
style: "opacity: 0.7;",
|
|
|
|
},
|
|
|
|
genEl(token.children),
|
|
|
|
),
|
|
|
|
];
|
|
|
|
}
|
2018-12-05 12:11:54 +01:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
case "center": {
|
|
|
|
return [
|
|
|
|
h(
|
|
|
|
"div",
|
|
|
|
{
|
|
|
|
style: "text-align:center;",
|
|
|
|
},
|
|
|
|
genEl(token.children),
|
|
|
|
),
|
|
|
|
];
|
|
|
|
}
|
2018-11-25 05:36:40 +01:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
case "url": {
|
|
|
|
return [
|
|
|
|
h(MkUrl, {
|
|
|
|
key: Math.random(),
|
|
|
|
url: token.props.url,
|
|
|
|
rel: "nofollow noopener",
|
|
|
|
}),
|
|
|
|
];
|
|
|
|
}
|
2018-03-31 14:41:08 +02:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
case "link": {
|
|
|
|
return [
|
|
|
|
h(
|
|
|
|
MkLink,
|
|
|
|
{
|
|
|
|
key: Math.random(),
|
|
|
|
url: token.props.url,
|
|
|
|
rel: "nofollow noopener",
|
|
|
|
},
|
|
|
|
genEl(token.children),
|
|
|
|
),
|
|
|
|
];
|
|
|
|
}
|
2018-03-31 14:41:08 +02:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
case "mention": {
|
|
|
|
return [
|
|
|
|
h(MkMention, {
|
|
|
|
key: Math.random(),
|
|
|
|
host:
|
|
|
|
(token.props.host == null &&
|
|
|
|
this.author &&
|
|
|
|
this.author.host != null
|
|
|
|
? this.author.host
|
|
|
|
: token.props.host) || host,
|
|
|
|
username: token.props.username,
|
|
|
|
}),
|
|
|
|
];
|
|
|
|
}
|
2018-03-31 14:41:08 +02:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
case "hashtag": {
|
|
|
|
return [
|
|
|
|
h(
|
|
|
|
MkA,
|
|
|
|
{
|
|
|
|
key: Math.random(),
|
2023-04-20 06:00:01 +02:00
|
|
|
to: `/tags/${encodeURIComponent(token.props.hashtag)}`,
|
2023-01-13 05:40:33 +01:00
|
|
|
style: "color:var(--hashtag);",
|
|
|
|
},
|
|
|
|
`#${token.props.hashtag}`,
|
|
|
|
),
|
|
|
|
];
|
|
|
|
}
|
2018-03-31 14:41:08 +02:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
case "blockCode": {
|
|
|
|
return [
|
|
|
|
h(MkCode, {
|
|
|
|
key: Math.random(),
|
|
|
|
code: token.props.code,
|
|
|
|
lang: token.props.lang,
|
|
|
|
}),
|
|
|
|
];
|
|
|
|
}
|
2018-03-31 14:41:08 +02:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
case "inlineCode": {
|
|
|
|
return [
|
|
|
|
h(MkCode, {
|
|
|
|
key: Math.random(),
|
|
|
|
code: token.props.code,
|
|
|
|
inline: true,
|
|
|
|
}),
|
|
|
|
];
|
|
|
|
}
|
2018-03-31 14:41:08 +02:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
case "quote": {
|
|
|
|
if (!this.nowrap) {
|
2023-02-11 00:41:19 +01:00
|
|
|
return [h("blockquote", genEl(token.children))];
|
2023-01-13 05:40:33 +01:00
|
|
|
} else {
|
|
|
|
return [
|
|
|
|
h(
|
|
|
|
"span",
|
|
|
|
{
|
|
|
|
class: "quote",
|
|
|
|
},
|
|
|
|
genEl(token.children),
|
|
|
|
),
|
|
|
|
];
|
|
|
|
}
|
|
|
|
}
|
2018-03-31 14:41:08 +02:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
case "emojiCode": {
|
|
|
|
return [
|
|
|
|
h(MkEmoji, {
|
|
|
|
key: Math.random(),
|
|
|
|
emoji: `:${token.props.name}:`,
|
|
|
|
customEmojis: this.customEmojis,
|
|
|
|
normal: this.plain,
|
|
|
|
}),
|
|
|
|
];
|
|
|
|
}
|
2021-04-02 03:36:11 +02:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
case "unicodeEmoji": {
|
|
|
|
return [
|
|
|
|
h(MkEmoji, {
|
|
|
|
key: Math.random(),
|
|
|
|
emoji: token.props.emoji,
|
|
|
|
customEmojis: this.customEmojis,
|
|
|
|
normal: this.plain,
|
|
|
|
}),
|
|
|
|
];
|
|
|
|
}
|
2018-03-31 14:41:08 +02:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
case "mathInline": {
|
|
|
|
return [
|
|
|
|
h(MkFormula, {
|
|
|
|
key: Math.random(),
|
|
|
|
formula: token.props.formula,
|
|
|
|
block: false,
|
|
|
|
}),
|
|
|
|
];
|
|
|
|
}
|
2019-01-25 15:08:06 +01:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
case "mathBlock": {
|
|
|
|
return [
|
|
|
|
h(MkFormula, {
|
|
|
|
key: Math.random(),
|
|
|
|
formula: token.props.formula,
|
|
|
|
block: true,
|
|
|
|
}),
|
|
|
|
];
|
|
|
|
}
|
2018-11-16 09:03:52 +01:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
case "search": {
|
2023-04-10 07:42:17 +02:00
|
|
|
// Disable "search" keyword
|
|
|
|
// (see the issue #9816 on Codeberg)
|
2023-04-15 19:53:17 +02:00
|
|
|
if (token.props.content.slice(-6).toLowerCase() === "search") {
|
2023-04-10 07:42:17 +02:00
|
|
|
const sentinel = "#";
|
|
|
|
let ast2 = (isPlain ? mfm.parseSimple : mfm.parse)(
|
|
|
|
token.props.content.slice(0, -6) + sentinel,
|
|
|
|
);
|
|
|
|
if (
|
|
|
|
ast2[ast2.length - 1].type === "text" &&
|
|
|
|
ast2[ast2.length - 1].props.text.endsWith(sentinel)
|
|
|
|
) {
|
|
|
|
ast2[ast2.length - 1].props.text = ast2[
|
|
|
|
ast2.length - 1
|
|
|
|
].props.text.slice(0, -1);
|
2023-04-15 19:53:17 +02:00
|
|
|
} else {
|
|
|
|
// I don't think this scope is reachable
|
|
|
|
console.warn(
|
|
|
|
"Something went wrong while parsing MFM. Please send a bug report, if possible.",
|
|
|
|
);
|
2023-04-10 07:42:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
let prefix = "\n";
|
|
|
|
if (
|
|
|
|
index === 0 ||
|
2023-04-15 19:53:17 +02:00
|
|
|
[
|
|
|
|
"blockCode",
|
|
|
|
"center",
|
|
|
|
"mathBlock",
|
|
|
|
"quote",
|
|
|
|
"search",
|
|
|
|
].includes(ast[index - 1].type)
|
2023-04-10 07:42:17 +02:00
|
|
|
) {
|
|
|
|
prefix = "";
|
|
|
|
}
|
|
|
|
|
2023-04-15 19:53:17 +02:00
|
|
|
return [
|
|
|
|
prefix,
|
|
|
|
...genEl(ast2),
|
|
|
|
`${token.props.content.slice(-6)}\n`,
|
|
|
|
];
|
2023-04-10 07:42:17 +02:00
|
|
|
}
|
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
return [
|
|
|
|
h(MkGoogle, {
|
|
|
|
key: Math.random(),
|
|
|
|
q: token.props.query,
|
|
|
|
}),
|
|
|
|
];
|
|
|
|
}
|
2018-04-21 11:59:16 +02:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
case "plain": {
|
|
|
|
return [h("span", genEl(token.children))];
|
|
|
|
}
|
2022-07-12 05:03:38 +02:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
default: {
|
|
|
|
console.error("unrecognized ast type:", token.type);
|
2018-09-11 20:32:47 +02:00
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
return [];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
);
|
2018-03-31 14:41:08 +02:00
|
|
|
|
2018-11-20 21:11:00 +01:00
|
|
|
// Parse ast to DOM
|
2023-01-13 05:40:33 +01:00
|
|
|
return h("span", genEl(ast));
|
2022-06-23 14:46:15 +02:00
|
|
|
},
|
2018-03-31 14:41:08 +02:00
|
|
|
});
|