Skip to content

Commit

Permalink
feat(syntax-highlight): move prism to the client
Browse files Browse the repository at this point in the history
  • Loading branch information
fiji-flo committed Jun 20, 2024
1 parent 118f71b commit edbdcd0
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 49 deletions.
14 changes: 3 additions & 11 deletions build/syntax-highlight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import Prism from "prismjs";
import loadLanguages from "prismjs/components/index.js";
import "prism-svelte";
import * as cheerio from "cheerio";
import { createHmac } from "node:crypto";
import { SAMPLE_SIGN_KEY } from "../libs/env/index.js";

const lazy = (creator) => {
let res;
Expand Down Expand Up @@ -110,13 +108,6 @@ export function syntaxHighlight($: cheerio.CheerioAPI, doc) {
return;
}
const code = $pre.text();
if (SAMPLE_SIGN_KEY) {
const hmac = createHmac("sha256", SAMPLE_SIGN_KEY);
hmac.update(name.toLowerCase());
hmac.update(code);
const signature = hmac.digest("base64");
$pre.attr("data-signature", signature);
}
$pre.wrapAll(`<div class='code-example'></div>`);
if (!$pre.hasClass("hidden")) {
$(
Expand All @@ -130,8 +121,9 @@ export function syntaxHighlight($: cheerio.CheerioAPI, doc) {
);
return; // bail!
}
const html = Prism.highlight(code, grammar, name);
const $code = $("<code>").html(html);
//const html = Prism.highlight(code, grammar, name);
//const $code = $("<code>").html(html);
const $code = $("<code>").text(code);

$pre.empty().append($code);
});
Expand Down
77 changes: 77 additions & 0 deletions client/src/document/highlight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import Prism from "prismjs";

const LANGS = [
"apacheconf",
"bash",
"batch",
"c",
"cpp",
"cs",
"diff",
"django",
"glsl",
"handlebars",
"http",
"ignore",
"ini",
"java",
"json",
"jsx",
"latex",
"less",
"md",
"nginx",
"php",
"powershell",
"pug",
"python",
"regex",
"rust",
"scss",
"sql",
// 'svelte', // Loaded by `prism-svelte` extension
"toml",
"tsx",
"typescript",
"uri",
"wasm",
"webidl",
"yaml",
];
// Add things to this list to help make things convenient. Sometimes
// there are `<pre class="brush: foo">` whose name is not that which
// Prism expects. It'd be hard to require that content writers
// have to stick to the exact naming conventions that Prism uses
// because Prism is an implementation detail.
const ALIASES = new Map([
["sh", "shell"],
["vue", "markup"], // See https://github.com/PrismJS/prism/issues/1665#issuecomment-536529608
]);

// Over the years we have accumulated some weird <pre> tags whose
// brush is more or less "junk".
// TODO: Perhaps, if you have a doc with <pre> tags that matches
// this, it should become a flaw.

const IGNORE = new Set(["none", "text", "plain", "unix"]);

export async function highlightSyntax(element: Element, language: string) {
const resolvedLanguage = ALIASES.get(language) || language;
if (IGNORE.has(resolvedLanguage)) {
return;
}

let prismLanguage = Prism.languages[resolvedLanguage];
if (!prismLanguage) {
if (LANGS.includes(resolvedLanguage)) {
await import(`prismjs/components/prism-${resolvedLanguage}.js`);
} else if (resolvedLanguage === "svelte") {
await import("prism-svelte");
}
}
prismLanguage = Prism.languages[resolvedLanguage];

if (prismLanguage) {
element.innerHTML = Prism.highlight(element.textContent, prismLanguage);
}
}
7 changes: 6 additions & 1 deletion client/src/document/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from "./code/playground";
import { addCopyToClipboardButton } from "./code/copy";
import { useUIStatus } from "../ui-context";
import { highlightSyntax } from "./highlight";

export function useDocumentURL() {
const locale = useLocale();
Expand Down Expand Up @@ -110,7 +111,7 @@ export function useCopyExamplesToClipboardAndAIExplain(doc: Doc | undefined) {

document
.querySelectorAll("div.code-example pre:not(.hidden)")
.forEach((element) => {
.forEach(async (element) => {
const header = element.parentElement?.querySelector(".example-header");
// Paused for now
// addExplainButton(header, element);
Expand All @@ -120,6 +121,10 @@ export function useCopyExamplesToClipboardAndAIExplain(doc: Doc | undefined) {
);
return;
} else {
await highlightSyntax(
element,
header?.querySelector(".language-name")?.textContent || "plain"
);
addCopyToClipboardButton(element, header);
}
});
Expand Down
4 changes: 2 additions & 2 deletions kumascript/macros/EmbedLiveSample.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ var MIN_HEIGHT = 60;
// Note that if the 'height' is a string like '100%' it won't be a
// problem because `parseInt('100%') := 100` which is more than `MIN_HEIGHT`
// assuming it's value is less than 100.
if (height && parseInt(height) < MIN_HEIGHT) {
height = MIN_HEIGHT;
if (height) {
height = Math.max(parseInt(height), MIN_HEIGHT);
}
var sampleUrl = "";
Expand Down
14 changes: 7 additions & 7 deletions kumascript/src/api/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,11 @@
*/
import sanitizeFilename from "sanitize-filename";
import * as cheerio from "cheerio";
import chalk from "chalk";

const H1_TO_H6_TAGS = new Set(["h1", "h2", "h3", "h4", "h5", "h6"]);
const HEADING_TAGS = new Set([...H1_TO_H6_TAGS, "hgroup"]);
const INJECT_SECTION_ID_TAGS = new Set([
...HEADING_TAGS,
"section",
"div",
"dt",
]);
const INJECT_SECTION_ID_TAGS = new Set([...HEADING_TAGS, "section", "dt"]);
const LIVE_SAMPLE_PARTS = ["html", "css", "js"];
const SECTION_ID_DISALLOWED = /["#$%&+,/:;=?@[\]^`{|}~')(\\]/g;

Expand Down Expand Up @@ -130,7 +126,6 @@ function collectClosestCode($start) {
];
});
if (pairs.some(([, code]) => !!code)) {
$start.prop("title", $level.first(":header").text());
return Object.fromEntries(pairs);
}
}
Expand Down Expand Up @@ -316,6 +311,11 @@ export class HTMLTool {
// We're here because we can't find the sectionID, so instead we're going
// to find the live-sample iframe by its id (iframeID, NOT sectionID), and
// then collect the closest blocks of code for the live sample.
console.warn(
chalk.yellow(
`invalid header id in live sample ${sectionID} within ${this.pathDescription}`
)
);
result = collectClosestCode(findSectionStart(this.$, iframeID));
if (!result) {
throw new KumascriptError(
Expand Down
32 changes: 4 additions & 28 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -14466,7 +14466,7 @@ string-natural-compare@^3.0.1:
resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4"
integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==

"string-width-cjs@npm:string-width@^4.2.0":
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
Expand All @@ -14492,15 +14492,6 @@ string-width@^3.0.0:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0"

string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"

string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
Expand Down Expand Up @@ -14631,7 +14622,7 @@ stringify-entities@^4.0.0:
character-entities-html4 "^2.0.0"
character-entities-legacy "^3.0.0"

"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
Expand All @@ -14652,13 +14643,6 @@ strip-ansi@^5.1.0:
dependencies:
ansi-regex "^4.1.0"

strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"

strip-ansi@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2"
Expand Down Expand Up @@ -16298,7 +16282,8 @@ word-wrap@~1.2.3:
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.4.tgz#cb4b50ec9aca570abd1f52f33cd45b6c61739a9f"
integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==

"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
name wrap-ansi-cjs
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
Expand All @@ -16316,15 +16301,6 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
Expand Down

0 comments on commit edbdcd0

Please sign in to comment.