Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(demo): Add a demo site #2

Merged
merged 1 commit into from
May 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,14 @@ jobs:
node-version: 14
- name: Install dependencies
run: npm ci
- run: npm run build
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-release
run: npx semantic-release
- name: Pages
uses: JamesIves/github-pages-deploy-action@4.1.3
with:
branch: gh-pages
folder: demo
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
dist
node_modules
demo/demo.mjs

.idea
*.iml
3 changes: 3 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"trailingComma": "all"
}
39 changes: 39 additions & 0 deletions build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const esbuild = require("esbuild");

const commonOptions = {
entryPoints: ["./src/index.ts"],
platform: "node",
target: "node14",
logLevel: "debug",
watch: process.env.WATCH === "true",
};

const buildEsm = () =>
esbuild.build({
...commonOptions,
format: "esm",
outdir: "dist/esm",
});

const buildCjs = () =>
esbuild.build({
...commonOptions,
bundle: true,
external: ["shiki"],
format: "cjs",
outdir: "dist/cjs",
});

const buildDemo = () =>
esbuild.build({
...commonOptions,
entryPoints: ["demo/demo.src.js"],
bundle: true,
platform: "browser",
format: "esm",
outfile: "demo/demo.mjs",
});

buildEsm(process.env.WATCH);
buildCjs(process.env.WATCH);
buildDemo(process.env.WATCH);
65 changes: 65 additions & 0 deletions demo/demo.src.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import unified from "unified";
import rehypeParse from "rehype-parse";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import rehypePluginAdvancedCode from "../src/index";
import rehypeStringify from "rehype-stringify";
import { setCDN } from "shiki";

setCDN("https://unpkg.com/shiki/");

const previewRemarkDiv = document.getElementById("previewRemark");
const previewRehypeDiv = document.getElementById("previewRehype");
const editorRemark = document.getElementById("editorRemark");
const editorRehype = document.getElementById("editorRehype");
const submitRemark = document.getElementById("submitRemark");
const submitRehype = document.getElementById("submitRehype");

function convertRehype() {
unified()
.use(rehypeParse)
.use(rehypePluginAdvancedCode)
.use(rehypeStringify)
.process(editorRehype.value)
.then((newMarkup) => {
previewRehypeDiv.innerHTML = newMarkup.contents;
});
}

editorRehype.addEventListener("keypress", (event) => {
if (event.ctrlKey && event.code === "Enter") {
convertRehype();
}
});

submitRehype.addEventListener("click", (e) => {
e.preventDefault();
convertRehype();
});

convertRehype();

function convertRemark() {
unified()
.use(remarkParse)
.use(remarkRehype)
.use(rehypePluginAdvancedCode)
.use(rehypeStringify)
.process(editorRemark.value)
.then((newMarkup) => {
previewRemarkDiv.innerHTML = newMarkup.contents;
});
}

editorRemark.addEventListener("keypress", (event) => {
if (event.ctrlKey && event.code === "Enter") {
convertRemark();
}
});

submitRemark.addEventListener("click", (e) => {
e.preventDefault();
convertRemark();
});

convertRemark();
58 changes: 58 additions & 0 deletions demo/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Rehype plugin advanced code</title>

<style type="text/css">
.columns {
width: 100%;
display: grid;
grid-template-columns: 50% 50%;
}
.columns > div {
padding: 1em;
}
textarea {
width: 100%;
height: 300px;
resize: vertical;
}
</style>
</head>
<body>
<h1>Transform code with unified</h1>

<p>Type HTML markup below, then click the button or press ctrl+enter</p>
<div class="columns">
<form>
<button id="submitRehype">Convert Html</button>
<textarea id="editorRehype"><pre id="theCode"><code class="language-rust">
fn main() {
// Print text to the console
println!("Hello World!");
}</code></pre>
</textarea>
</form>
<div id="previewRehype"></div>
</div>

<div class="columns">
<form>
<button id="submitRemark">Convert Markdown</button>
<textarea id="editorRemark">
```javascript
function hello(name) {
console.log(`Hello, ${name}!`);
}
```
</textarea>
</form>
<div id="previewRemark"></div>
</div>

<script type="module" src="demo.mjs"></script>
</body>
</html>
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@
"main": "index.js",
"scripts": {
"test": "jest",
"lint": "eslint src/**.ts",
"dev": "esbuild src/index.ts --bundle --platform=node --external:shiki --target=node14 --format=cjs --sourcemap --watch --outdir=dist/cjs",
"build": "tsc -b src/tsconfig.json && npm run build:cjs && npm run build:esm",
"build:esm": "esbuild src/index.ts --platform=node --target=node14 --format=esm --outdir=dist/esm",
"build:cjs": "esbuild src/index.ts --bundle --platform=node --external:shiki --target=node14 --format=cjs --outdir=dist/cjs",
"lint": "eslint src/**.ts demo/**.js",
"dev": "WATCH=true node build.js",
"build": "node build.js",
"prepublishOnly": "npm run build",
"semantic-release": "semantic-release"
},
Expand All @@ -33,6 +31,10 @@
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.js"
},
"browser": {
"path": false,
"fs": false
},
"homepage": "https://github.com/BenoitAverty/rehype-plugin-advanced-code#readme",
"devDependencies": {
"@semantic-release/changelog": "^5.0.1",
Expand Down
89 changes: 54 additions & 35 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Attacher } from "unified";
import type { Element, Properties } from "hast";
import { visit } from "unist-util-visit";
import { h } from "hastscript";
import { getHighlighter, Highlighter } from "shiki";
import { getHighlighter, Highlighter, Lang } from "shiki";
import { Parent } from "unist";

interface CodeNode extends Element {
Expand All @@ -27,14 +27,14 @@ function parseMeta(value: string | null | undefined): CodeMetadata {
: { highlightedLines: [] };
}

function parseLanguage(className?: string): string | null {
function parseLanguage(className?: string): Lang | null {
if (!className || className === "") return null;

const languageClasses = className
.split(" ")
.filter((c) => c.startsWith("language-"))
.map((c) => c.substring(c.indexOf("-") + 1));
return languageClasses.length > 0 ? languageClasses[0] : null;
return languageClasses.length > 0 ? (languageClasses[0] as Lang) : null;
}

function transformInlineCode(
Expand All @@ -43,7 +43,7 @@ function transformInlineCode(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
lang: string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
node: CodeNode
node: CodeNode,
) {
// TODO
}
Expand All @@ -52,7 +52,7 @@ function transformCodeBlock(
highlighter: Highlighter,
lang: string,
node: CodeNode,
parent: PreNode
parent: PreNode,
) {
const meta = parseMeta(node.data?.meta);

Expand All @@ -70,10 +70,10 @@ function transformCodeBlock(
h(
"span",
{ style: `color: ${token.color || "inherit"}` },
token.content
)
)
)
token.content,
),
),
),
);

// Colors on the "pre" element
Expand All @@ -87,37 +87,56 @@ function transformCodeBlock(
}

const advancedCodeBlock: Attacher = function advancedCodeBlock() {
const transformCode =
(highlighter: Highlighter) =>
(node: CodeNode, index: number | null, parent: Parent | null) => {
const lang = parseLanguage(String(node.properties?.className));

if (
lang === null ||
node.children.length !== 1 ||
node.children[0].type !== "text"
) {
return;
}

if (
parent === null ||
parent.type !== "element" ||
parent.tagName !== "pre"
) {
return transformInlineCode(highlighter, lang, node);
} else {
return transformCodeBlock(highlighter, lang, node, parent as PreNode);
}
};
const transformCode = async (
node: CodeNode,
index: number | null,
parent: Parent | null,
) => {
const lang: Lang | null = parseLanguage(String(node.properties?.className));

if (
lang === null ||
node.children.length !== 1 ||
node.children[0].type !== "text"
) {
return;
}

if (
parent === null ||
parent.type !== "element" ||
parent.tagName !== "pre"
) {
const highlighter = await getHighlighter({
theme: "monokai",
langs: [lang],
});
return transformInlineCode(highlighter, lang, node);
} else {
const highlighter = await getHighlighter({
theme: "monokai",
langs: [lang],
});
return transformCodeBlock(highlighter, lang, node, parent as PreNode);
}
};

return async function codeBlockProcessor(tree) {
const highlighter = await getHighlighter({ theme: "monokai" });

const nodes: Array<{
node: CodeNode;
index: number | null;
parent: Parent | null;
}> = [];
visit<CodeNode>(
tree,
{ type: "element", tagName: "code" },
transformCode(highlighter)
(node, index, parent) => nodes.push({ node, index, parent }),
);

await Promise.all(
nodes.map(({ node, index, parent }) =>
transformCode(node, index, parent),
),
);
};
};
Expand Down