diff --git a/build-scripts/social-previews/layouts/banner-css.ts b/build-scripts/social-previews/layouts/banner-css.ts
index 8216809a..e5af440b 100644
--- a/build-scripts/social-previews/layouts/banner-css.ts
+++ b/build-scripts/social-previews/layouts/banner-css.ts
@@ -5,6 +5,31 @@ export default `
font-family: 'Roboto Mono', monospace;
}
+pre {
+ counter-reset: step;
+ counter-increment: step 0;
+}
+
+pre code {
+ display: block;
+ position: relative;
+ padding-left: 3.5rem;
+ tab-size: 4;
+ height: 1.4rem;
+}
+
+pre code::before {
+ content: counter(step);
+ counter-increment: step;
+
+ position: absolute;
+ left: 1rem;
+ width: 1rem;
+ display: inline-block;
+ text-align: right;
+ color: var(--foreground_disabled);
+}
+
.theme-0 {
--color-screen-background: #FFF;
--color-screen-border: #CCC;
diff --git a/build-scripts/social-previews/layouts/banner.tsx b/build-scripts/social-previews/layouts/banner.tsx
index 2ffdf6c2..b46fd6a2 100644
--- a/build-scripts/social-previews/layouts/banner.tsx
+++ b/build-scripts/social-previews/layouts/banner.tsx
@@ -65,7 +65,7 @@ function BannerCodeScreen({
style={`--rotX: ${rotX}deg; --rotY: ${rotY}deg; --left: ${rotY}%;`}
>
-
+
{post.tags.map((tag) => (
{tag}
diff --git a/build-scripts/social-previews/shared-post-preview-png.ts b/build-scripts/social-previews/shared-post-preview-png.ts
index aeb957eb..5b785146 100644
--- a/build-scripts/social-previews/shared-post-preview-png.ts
+++ b/build-scripts/social-previews/shared-post-preview-png.ts
@@ -1,65 +1,60 @@
import { readFileAsBase64 } from "./utils";
import { ExtendedPostInfo } from "types/index";
-import * as fs from "fs";
import { render } from "preact-render-to-string";
import { createElement } from "preact";
import { unified } from "unified";
import remarkParse from "remark-parse";
-import { default as remarkTwoslashDefault } from "remark-shiki-twoslash";
import remarkToRehype from "remark-rehype";
import { findAllAfter } from "unist-util-find-all-after";
+import { toString } from "hast-util-to-string";
import rehypeStringify from "rehype-stringify";
import { Layout, PAGE_HEIGHT, PAGE_WIDTH } from "./base";
-import { Literal } from "unist";
-// https://github.com/shikijs/twoslash/issues/147
-const remarkTwoslash =
- (remarkTwoslashDefault as never as { default: typeof remarkTwoslashDefault })
- .default ?? remarkTwoslashDefault;
+const unifiedChain = unified()
+ .use(remarkParse)
+ .use(remarkToRehype, { allowDangerousHtml: true })
+ .use(() => (tree) => {
+ // extract code snippets from parsed markdown
+ const nodes = findAllAfter(tree, 0, { tagName: "pre" });
-const unifiedChain = () => {
- const unifiedChain = unified()
- .use(remarkParse)
- .use(() => (tree) => {
- // extract code snippets from parsed markdown
- const nodes = findAllAfter(tree, 0, { type: "code" });
+ // join code parts into one element
+ const value =
+ nodes
+ .map((node) => toString(node))
+ .join("\n")
+ .trim() +
+ "\n" +
+ renderPostPreviewToString.toString().replace(/([;,])/g, (s) => s + "\n");
- // join code parts into one element
- const value =
- nodes
- .map((node) => (node as Literal).value)
- .join("\n")
- .trim() +
- "\n" +
- renderPostPreviewToString
- .toString()
- .replace(/([;,])/g, (s) => s + "\n");
+ const children = value.split("\n").map((value) => ({
+ type: "element",
+ tagName: "code",
+ children: [
+ {
+ type: "text",
+ value,
+ },
+ ],
+ }));
- return {
- type: "root",
- children: [
- {
- type: "code",
- lang: (nodes[0] as { lang?: string })?.lang || "javascript",
- value,
- },
- ],
- };
- })
- .use([[remarkTwoslash, { themes: ["css-variables"] }]])
- .use(remarkToRehype, { allowDangerousHtml: true })
- .use(rehypeStringify, { allowDangerousHtml: true });
-
- return unifiedChain;
-};
+ return {
+ type: "root",
+ children: [
+ {
+ type: "element",
+ tagName: "pre",
+ children,
+ },
+ ],
+ };
+ })
+ .use(rehypeStringify, { allowDangerousHtml: true });
async function markdownToHtml(content: string) {
- return await (await unifiedChain().process(content)).toString();
+ return await (await unifiedChain.process(content)).toString();
}
-const shikiSCSS = fs.readFileSync("src/styles/shiki.scss", "utf8");
-
export const renderPostPreviewToString = async (
layout: Layout,
post: ExtendedPostInfo,
@@ -78,9 +73,6 @@ export const renderPostPreviewToString = async (
-