slint/docs/astro/ec.config.mjs

201 lines
5.8 KiB
JavaScript

// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { definePlugin } from "@expressive-code/core";
import { h } from "@expressive-code/core/hast";
import fs from "node:fs";
import { pluginLineNumbers } from "@expressive-code/plugin-line-numbers";
function sideBorder() {
return definePlugin({
name: "Adds side border to slint code blocks",
baseStyles: `
.sideBar {
position: absolute;
top: calc(var(--button-spacing) - 6px);
bottom: 0;
left: 0;
width: 100px;
border-left-width: 2px;
border-left-style: solid;
border-color: #2479f4;
border-top-left-radius: 0.4rem;
border-bottom-left-radius: 0.4rem;
pointer-events: none;
}
`,
hooks: {
postprocessRenderedBlock: (context) => {
if (
context.renderData.blockAst.children[1].properties
.dataLanguage !== "slint"
) {
return;
}
const side = h("div.sideBar");
const ast = context.renderData.blockAst;
ast.children.push(side);
context.renderData.blockAst = ast;
},
},
});
}
function remapLanguageIdentifiers(lang) {
switch (lang) {
case "cpp": {
return "C++";
}
case "sh": {
return "bash";
}
default: {
return lang;
}
}
}
function languageLabel() {
return definePlugin({
name: "Adds language label to code blocks",
baseStyles: `
.language-label {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
inset-block-start: calc(var(--ec-brdWd) + var(--button-spacing));
inset-inline-end: calc(var(--ec-brdWd) + var(--ec-uiPadInl) );
direction: ltr;
font-size: 0.8rem;
color:rgb(169, 169, 169);
opacity: 1;
transition: opacity 0.3s;
}
div.expressive-code:hover .language-label,
.expressive-code:hover .language-label {
opacity: 0;
}
`,
hooks: {
postprocessRenderedBlock: (context) => {
const language =
context.renderData.blockAst.children[1].properties
.dataLanguage;
const label = h("div.language-label", {}, [
remapLanguageIdentifiers(language),
]);
const ast = context.renderData.blockAst;
ast.children.push(label);
context.renderData.blockAst = ast;
},
},
});
}
function workersPlaygroundButton() {
return definePlugin({
name: "Adds 'Run in SlintPad' button to slint codeblocks",
baseStyles: `
.run {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
inset-block-start: calc(var(--ec-brdWd) + var(--button-spacing));
inset-inline-end: calc(var(--ec-brdWd) + var(--ec-uiPadInl) * 3);
direction: ltr;
unicode-bidi: isolate;
background-color: color-mix(in srgb, var(--sl-color-accent) 50%, transparent);
color: var(--sl-color-white);
text-decoration: none;
width: 2rem;
height: 2rem;
border-radius: 50%;
opacity: 0;
font-size: 0;
transition: opacity 0.3s, background-color 0.3s;
&:hover {
background-color: color-mix(in srgb, var(--sl-color-accent) 90%, transparent);
}
&::before {
content: '';
display: inline-block;
margin-left: 0.25rem;
border-style: solid;
border-width: 0.5rem 0 0.5rem 0.75rem;
border-color: transparent transparent transparent white;
}
}
div.expressive-code:hover .run,
.expressive-code:hover .run {
opacity: 1;
}
`,
hooks: {
postprocessRenderedBlock: (context) => {
if (!context.codeBlock.meta.includes("playground")) {
return;
}
const content = context.codeBlock.code;
const url = `https://slintpad.com?snippet=${encodeURIComponent(content)}`;
const runButton = h(
"a.run",
{
href: url,
target: "__blank",
title: "Open in SlintPad",
},
[],
);
const ast = context.renderData.blockAst;
ast.children.push(runButton);
context.renderData.blockAst = ast;
},
},
});
}
export default {
plugins: [
workersPlaygroundButton(),
sideBorder(),
languageLabel(),
pluginLineNumbers(),
],
defaultProps: {
showLineNumbers: false,
},
themes: ["dark-plus", "light-plus"],
styleOverrides: {
borderRadius: "0.4rem",
borderColor: "var(--slint-code-background)",
frames: { shadowColor: "transparent" },
codeBackground: "var(--slint-code-background)",
},
shiki: {
langs: [
JSON.parse(
fs.readFileSync(
"../../editors/vscode/slint.tmLanguage.json",
"utf-8",
),
),
],
},
frames: {
extractFileNameFromCode: false,
},
};