Refactor code language and ts types (#9300)
* 🎨 Code block language list adds custom languages * Update index.d.ts * 🎨 Improve global variable type definition * 🎨 Improve global variable type definition * 🎨 Add constant `EXTRA_CODE_LANGUAGES`
This commit is contained in:
parent
17d2a16a94
commit
b2a27bb54c
16 changed files with 86 additions and 72 deletions
|
@ -541,9 +541,13 @@ export abstract class Constants {
|
|||
public static readonly INLINE_TYPE: string[] = ["block-ref", "kbd", "text", "file-annotation-ref", "a", "strong", "em", "u", "s", "mark", "sup", "sub", "tag", "code", "inline-math", "inline-memo"];
|
||||
public static readonly BLOCK_HINT_KEYS: string[] = ["((", "[[", "((", "【【"];
|
||||
public static readonly BLOCK_HINT_CLOSE_KEYS: IObject = {"((": "))", "[[": "]]", "((": "))", "【【": "】】"};
|
||||
public static readonly CODE_LANGUAGES: string[] = [
|
||||
public static readonly EXTRA_CODE_LANGUAGES: string[] = [
|
||||
// 同名
|
||||
"js", "ts", "html", "toml", "c#", "bat",
|
||||
];
|
||||
public static readonly CODE_LANGUAGES: string[] = [
|
||||
// 附加
|
||||
...Constants.EXTRA_CODE_LANGUAGES,
|
||||
// common
|
||||
"bash", "c", "csharp", "cpp", "css", "diff", "go", "xml", "json", "java", "javascript", "kotlin", "less", "lua", "makefile", "markdown", "objectivec", "php", "php-template", "perl", "plaintext", "python", "python-repl", "r", "ruby", "rust", "scss", "sql", "shell", "swift", "ini", "typescript", "vbnet", "yaml", "properties", "1c", "armasm", "avrasm", "actionscript", "ada", "angelscript", "accesslog", "apache", "applescript", "arcade", "arduino", "asciidoc", "aspectj", "abnf", "autohotkey", "autoit", "awk", "basic", "bnf", "dos", "brainfuck", "cal", "cmake", "csp", "cos", "capnproto", "ceylon", "clean", "clojure", "clojure-repl", "coffeescript", "coq", "crystal", "d", "dns", "dart", "delphi", "dts", "django", "dockerfile", "dust", "erb", "elixir", "elm", "erlang", "erlang-repl", "excel", "ebnf", "fsharp", "fix", "flix", "fortran", "gcode", "gams", "gauss", "glsl", "gml", "gherkin", "golo", "gradle", "groovy", "haml", "hsp", "http", "handlebars", "haskell", "haxe", "hy", "irpf90", "isbl", "inform7", "x86asm", "jboss-cli", "julia", "julia-repl", "ldif", "llvm", "lsl", "latex", "lasso", "leaf", "lisp", "livecodeserver", "livescript", "mel", "mipsasm", "matlab", "maxima", "mercury", "axapta", "routeros", "mizar", "mojolicious", "monkey", "moonscript", "n1ql", "nsis", "nestedtext", "nginx", "nim", "nix", "node-repl", "ocaml", "openscad", "ruleslanguage", "oxygene", "pf", "parser3", "pony", "pgsql", "powershell", "processing", "prolog", "protobuf", "puppet", "purebasic", "profile", "q", "qml", "reasonml", "rib", "rsl", "roboconf", "sas", "sml", "sqf", "step21", "scala", "scheme", "scilab", "smali", "smalltalk", "stan", "stata", "stylus", "subunit", "tp", "taggerscript", "tcl", "tap", "thrift", "twig", "vbscript", "vbscript-html", "vhdl", "vala", "verilog", "vim", "wasm", "mathematica", "wren", "xl", "xquery", "zephir", "crmsh", "dsconfig", "graphql",
|
||||
// third
|
||||
|
|
|
@ -1218,7 +1218,7 @@ export class Gutter {
|
|||
updateTransaction(protyle, id, nodeElement.outerHTML, html);
|
||||
html = nodeElement.outerHTML;
|
||||
event.stopPropagation();
|
||||
const chartInstance = echarts.getInstanceById(nodeElement.firstElementChild.nextElementSibling.getAttribute("_echarts_instance_"));
|
||||
const chartInstance = window.echarts.getInstanceById(nodeElement.firstElementChild.nextElementSibling.getAttribute("_echarts_instance_"));
|
||||
if (chartInstance) {
|
||||
chartInstance.resize();
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ export const previewDocImage = (src: string, id: string) => {
|
|||
});
|
||||
imagesElement.innerHTML = html;
|
||||
// @ts-ignore
|
||||
window.siyuan.viewer = new Viewer(imagesElement, {
|
||||
window.siyuan.viewer = new window.Viewer(imagesElement, {
|
||||
title: [1, (image: HTMLImageElement, imageData: IObject) => {
|
||||
let name = image.alt;
|
||||
if (!name) {
|
||||
|
|
|
@ -2,10 +2,6 @@ import {addScript} from "../util/addScript";
|
|||
import {Constants} from "../../constants";
|
||||
import {genIconHTML} from "./util";
|
||||
|
||||
declare const ABCJS: {
|
||||
renderAbc(element: Element, text: string, options: { responsive: string }): void;
|
||||
};
|
||||
|
||||
export const abcRender = (element: Element, cdn = Constants.PROTYLE_CDN) => {
|
||||
let abcElements: Element[] = [];
|
||||
if (element.getAttribute("data-subtype") === "abc") {
|
||||
|
@ -30,7 +26,7 @@ export const abcRender = (element: Element, cdn = Constants.PROTYLE_CDN) => {
|
|||
e.lastElementChild.insertAdjacentHTML("beforebegin", `<span style="position: absolute">${Constants.ZWSP}</span>`);
|
||||
}
|
||||
const renderElement = e.firstElementChild.nextElementSibling as HTMLElement;
|
||||
ABCJS.renderAbc(renderElement, Lute.UnEscapeHTMLStr(e.getAttribute("data-content")), {
|
||||
window.ABCJS.renderAbc(renderElement, Lute.UnEscapeHTMLStr(e.getAttribute("data-content")), {
|
||||
responsive: "resize"
|
||||
});
|
||||
renderElement.setAttribute("contenteditable", "false");
|
||||
|
|
|
@ -41,14 +41,14 @@ export const chartRender = (element: Element, cdn = Constants.PROTYLE_CDN) => {
|
|||
try {
|
||||
renderElement.style.height = e.style.height;
|
||||
const option = await looseJsonParse(Lute.UnEscapeHTMLStr(e.getAttribute("data-content")));
|
||||
echarts.init(renderElement, window.siyuan.config.appearance.mode === 1 ? "dark" : undefined, {width}).setOption(option);
|
||||
window.echarts.init(renderElement, window.siyuan.config.appearance.mode === 1 ? "dark" : undefined, {width}).setOption(option);
|
||||
e.setAttribute("data-render", "true");
|
||||
renderElement.classList.remove("ft__error");
|
||||
if (!renderElement.textContent.endsWith(Constants.ZWSP)) {
|
||||
renderElement.firstElementChild.insertAdjacentText("beforeend", Constants.ZWSP);
|
||||
}
|
||||
} catch (error) {
|
||||
echarts.dispose(renderElement);
|
||||
window.echarts.dispose(renderElement);
|
||||
renderElement.classList.add("ft__error");
|
||||
renderElement.innerHTML = `echarts render error: <br>${error}`;
|
||||
}
|
||||
|
|
|
@ -2,12 +2,6 @@ import {addScript} from "../util/addScript";
|
|||
import {Constants} from "../../constants";
|
||||
import {genIconHTML} from "./util";
|
||||
|
||||
declare class Viz {
|
||||
public renderSVGElement: (code: string) => Promise<any>;
|
||||
|
||||
constructor(worker: { worker: Worker });
|
||||
}
|
||||
|
||||
export const graphvizRender = (element: Element, cdn = Constants.PROTYLE_CDN) => {
|
||||
let graphvizElements: Element[] = [];
|
||||
if (element.getAttribute("data-subtype") === "graphviz") {
|
||||
|
@ -34,7 +28,7 @@ export const graphvizRender = (element: Element, cdn = Constants.PROTYLE_CDN) =>
|
|||
const url = window.URL || window.webkitURL;
|
||||
const blobUrl = url.createObjectURL(blob);
|
||||
const worker = new Worker(blobUrl);
|
||||
new Viz({worker})
|
||||
new window.Viz({worker})
|
||||
.renderSVGElement(Lute.UnEscapeHTMLStr(e.getAttribute("data-content"))).then((result: HTMLElement) => {
|
||||
renderElement.innerHTML = result.outerHTML;
|
||||
renderElement.classList.remove("ft__error");
|
||||
|
|
|
@ -66,7 +66,7 @@ export const highlightRender = (element: Element, cdn = Constants.PROTYLE_CDN) =
|
|||
// bazaar readme
|
||||
language = block.className.replace("language-", "");
|
||||
}
|
||||
if (!hljs.getLanguage(language)) {
|
||||
if (!window.hljs.getLanguage(language)) {
|
||||
language = "plaintext";
|
||||
}
|
||||
block.classList.add("hljs");
|
||||
|
@ -110,7 +110,7 @@ export const highlightRender = (element: Element, cdn = Constants.PROTYLE_CDN) =
|
|||
matchElement.scrollIntoView();
|
||||
}
|
||||
}
|
||||
block.innerHTML = hljs.highlight(
|
||||
block.innerHTML = window.hljs.highlight(
|
||||
block.textContent + (block.textContent.endsWith("\n") ? "" : "\n"), // https://github.com/siyuan-note/siyuan/issues/4609
|
||||
{
|
||||
language,
|
||||
|
|
|
@ -4,16 +4,6 @@ import {Constants} from "../../constants";
|
|||
import {hasNextSibling, hasPreviousSibling} from "../wysiwyg/getBlock";
|
||||
import {hasClosestBlock} from "../util/hasClosest";
|
||||
|
||||
declare const katex: {
|
||||
renderToString(math: string, option: {
|
||||
displayMode: boolean;
|
||||
output: string;
|
||||
macros: IObject;
|
||||
trust: boolean;
|
||||
strict: (errorCode:string) => "ignore" | "warn";
|
||||
}): string;
|
||||
};
|
||||
|
||||
export const mathRender = (element: Element, cdn = Constants.PROTYLE_CDN, maxWidth = false) => {
|
||||
let mathElements: Element[] = [];
|
||||
if (element.getAttribute("data-subtype") === "math") {
|
||||
|
@ -44,7 +34,7 @@ export const mathRender = (element: Element, cdn = Constants.PROTYLE_CDN, maxWid
|
|||
console.warn("KaTex macros is not JSON", e);
|
||||
}
|
||||
try {
|
||||
renderElement.innerHTML = katex.renderToString(Lute.UnEscapeHTMLStr(mathElement.getAttribute("data-content")), {
|
||||
renderElement.innerHTML = window.katex.renderToString(Lute.UnEscapeHTMLStr(mathElement.getAttribute("data-content")), {
|
||||
displayMode: mathElement.tagName === "DIV",
|
||||
output: "html",
|
||||
macros,
|
||||
|
|
|
@ -2,11 +2,6 @@ import {addScript} from "../util/addScript";
|
|||
import {Constants} from "../../constants";
|
||||
import {hasClosestByAttribute} from "../util/hasClosest";
|
||||
|
||||
declare const mermaid: {
|
||||
initialize(options: any): void,
|
||||
init(options: any, element: Element): void
|
||||
};
|
||||
|
||||
export const mermaidRender = (element: Element, cdn = Constants.PROTYLE_CDN) => {
|
||||
let mermaidElements: Element[] = [];
|
||||
if (element.getAttribute("data-subtype") === "mermaid") {
|
||||
|
@ -43,7 +38,7 @@ export const mermaidRender = (element: Element, cdn = Constants.PROTYLE_CDN) =>
|
|||
if (window.siyuan.config.appearance.mode === 1) {
|
||||
config.theme = "dark";
|
||||
}
|
||||
mermaid.initialize(config);
|
||||
window.mermaid.initialize(config);
|
||||
if (mermaidElements[0].firstElementChild.clientWidth === 0) {
|
||||
const hideElement = hasClosestByAttribute(mermaidElements[0], "fold", "1");
|
||||
if (!hideElement) {
|
||||
|
@ -75,7 +70,7 @@ const initMermaid = (mermaidElements: Element[]) => {
|
|||
renderElement.removeAttribute("data-processed");
|
||||
renderElement.textContent = Lute.UnEscapeHTMLStr(item.getAttribute("data-content"));
|
||||
setTimeout(() => {
|
||||
mermaid.init(undefined, renderElement);
|
||||
window.mermaid.init(undefined, renderElement);
|
||||
}, Constants.TIMEOUT_LOAD * index);
|
||||
item.setAttribute("data-render", "true");
|
||||
renderElement.setAttribute("contenteditable", "false");
|
||||
|
|
|
@ -37,7 +37,7 @@ export const mindmapRender = (element: Element, cdn = Constants.PROTYLE_CDN) =>
|
|||
const renderElement = e.firstElementChild.nextElementSibling as HTMLElement;
|
||||
try {
|
||||
renderElement.style.height = e.style.height;
|
||||
echarts.init(renderElement, window.siyuan.config.appearance.mode === 1 ? "dark" : undefined, {
|
||||
window.echarts.init(renderElement, window.siyuan.config.appearance.mode === 1 ? "dark" : undefined, {
|
||||
width,
|
||||
}).setOption({
|
||||
series: [
|
||||
|
|
|
@ -2,10 +2,6 @@ import {addScript} from "../util/addScript";
|
|||
import {Constants} from "../../constants";
|
||||
import {genIconHTML} from "./util";
|
||||
|
||||
declare const plantumlEncoder: {
|
||||
encode(options: string): string,
|
||||
};
|
||||
|
||||
export const plantumlRender = (element: Element, cdn = Constants.PROTYLE_CDN) => {
|
||||
let plantumlElements: Element[] = [];
|
||||
if (element.getAttribute("data-subtype") === "plantuml") {
|
||||
|
@ -27,7 +23,7 @@ export const plantumlRender = (element: Element, cdn = Constants.PROTYLE_CDN) =>
|
|||
}
|
||||
const renderElement = e.firstElementChild.nextElementSibling as HTMLElement;
|
||||
try {
|
||||
renderElement.innerHTML = `<img src=${window.siyuan.config.editor.plantUMLServePath}${plantumlEncoder.encode(Lute.UnEscapeHTMLStr(e.getAttribute("data-content")))}">`;
|
||||
renderElement.innerHTML = `<img src=${window.siyuan.config.editor.plantUMLServePath}${window.plantumlEncoder.encode(Lute.UnEscapeHTMLStr(e.getAttribute("data-content")))}">`;
|
||||
renderElement.classList.remove("ft__error");
|
||||
e.setAttribute("data-render", "true");
|
||||
} catch (error) {
|
||||
|
|
|
@ -1145,10 +1145,16 @@ export class Toolbar {
|
|||
this.range = getEditorRange(nodeElement);
|
||||
const id = nodeElement.getAttribute("data-node-id");
|
||||
let oldHtml = nodeElement.outerHTML;
|
||||
let html = `<div class="b3-list-item b3-list-item--focus">${window.siyuan.languages.clear}</div>`;
|
||||
Constants.CODE_LANGUAGES.forEach((item) => {
|
||||
html += `<div class="b3-list-item">${item}</div>`;
|
||||
});
|
||||
|
||||
const languages = Array.from(new Set<string>([
|
||||
...Constants.EXTRA_CODE_LANGUAGES,
|
||||
...(window.hljs?.listLanguages() ?? []),
|
||||
])).sort();
|
||||
const html = [
|
||||
`<div class="b3-list-item b3-list-item--focus">${window.siyuan.languages.clear}</div>`,
|
||||
...languages.map(item => `<div class="b3-list-item">${item}</div>`),
|
||||
].join("\n");
|
||||
|
||||
this.subElement.style.width = "";
|
||||
this.subElement.style.padding = "";
|
||||
this.subElement.innerHTML = `<div class="fn__flex-column" style="max-height:50vh"><input placeholder="${window.siyuan.languages.search}" style="margin: 0 8px 4px 8px" class="b3-text-field"/>
|
||||
|
@ -1189,18 +1195,13 @@ export class Toolbar {
|
|||
}
|
||||
});
|
||||
inputElement.addEventListener("input", (event) => {
|
||||
const matchLanguages: string[] = [];
|
||||
Constants.CODE_LANGUAGES.forEach((item) => {
|
||||
if (item.indexOf(inputElement.value.toLowerCase()) > -1) {
|
||||
matchLanguages.push(item);
|
||||
|
||||
}
|
||||
});
|
||||
const lowerCaseValue = inputElement.value.toLowerCase();
|
||||
const matchLanguages = languages.filter(item => item.includes(lowerCaseValue));
|
||||
let html = "";
|
||||
// sort
|
||||
let matchInput = false;
|
||||
matchLanguages.sort((a, b) => {
|
||||
if (a.startsWith(inputElement.value.toLowerCase()) && b.startsWith(inputElement.value.toLowerCase())) {
|
||||
if (a.startsWith(lowerCaseValue) && b.startsWith(lowerCaseValue)) {
|
||||
if (a.length < b.length) {
|
||||
return -1;
|
||||
} else if (a.length === b.length) {
|
||||
|
@ -1208,9 +1209,9 @@ export class Toolbar {
|
|||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else if (a.startsWith(inputElement.value.toLowerCase())) {
|
||||
} else if (a.startsWith(lowerCaseValue)) {
|
||||
return -1;
|
||||
} else if (b.startsWith(inputElement.value.toLowerCase())) {
|
||||
} else if (b.startsWith(lowerCaseValue)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
|
@ -1219,7 +1220,7 @@ export class Toolbar {
|
|||
if (inputElement.value === item) {
|
||||
matchInput = true;
|
||||
}
|
||||
html += `<div class="b3-list-item">${item.replace(inputElement.value.toLowerCase(), "<b>" + inputElement.value.toLowerCase() + "</b>")}</div>`;
|
||||
html += `<div class="b3-list-item">${item.replace(lowerCaseValue, "<b>" + lowerCaseValue + "</b>")}</div>`;
|
||||
});
|
||||
if (inputElement.value.trim() && !matchInput) {
|
||||
html = `<div class="b3-list-item"><b>${inputElement.value.replace(/`| /g, "_")}</b></div>${html}`;
|
||||
|
|
|
@ -11,9 +11,9 @@ export const resize = (protyle: IProtyle) => {
|
|||
// 不能 clearTimeout,否则 split 时左侧无法 resize
|
||||
setTimeout(() => {
|
||||
if (abs.width > MIN_ABS || isNaN(abs.width)) {
|
||||
if (typeof echarts !== "undefined") {
|
||||
if (typeof window.echarts !== "undefined") {
|
||||
protyle.wysiwyg.element.querySelectorAll('[data-subtype="echarts"], [data-subtype="mindmap"]').forEach((chartItem: HTMLElement) => {
|
||||
const chartInstance = echarts.getInstanceById(chartItem.firstElementChild.nextElementSibling.getAttribute("_echarts_instance_"));
|
||||
const chartInstance = window.echarts.getInstanceById(chartItem.firstElementChild.nextElementSibling.getAttribute("_echarts_instance_"));
|
||||
if (chartInstance) {
|
||||
chartInstance.resize();
|
||||
}
|
||||
|
|
|
@ -1579,10 +1579,10 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
|
|||
}
|
||||
const insertElement = document.createElement("span");
|
||||
let language = nodeElement.querySelector(".protyle-action__language").textContent;
|
||||
if (!hljs.getLanguage(language)) {
|
||||
if (!window.hljs.getLanguage(language)) {
|
||||
language = "plaintext";
|
||||
}
|
||||
insertElement.innerHTML = hljs.highlight(text.substr(0, text.length - 1), {
|
||||
insertElement.innerHTML = window.hljs.highlight(text.substr(0, text.length - 1), {
|
||||
language,
|
||||
ignoreIllegals: true
|
||||
}).value;
|
||||
|
|
9
app/src/types/index.d.ts
vendored
9
app/src/types/index.d.ts
vendored
|
@ -81,6 +81,15 @@ type TAVFilterOperator =
|
|||
declare module "blueimp-md5"
|
||||
|
||||
interface Window {
|
||||
ABCJS?: IABCJS
|
||||
Viewer?: Function
|
||||
Viz?: IViz
|
||||
echarts?: IECharts
|
||||
hljs?: IHLJS
|
||||
katex?: IKaTeX
|
||||
mermaid?: IMermaid
|
||||
plantumlEncoder?: IPlantumlEncoder
|
||||
|
||||
pdfjsLib: any
|
||||
dataLayer: any[]
|
||||
siyuan: ISiyuan
|
||||
|
|
49
app/src/types/protyle.d.ts
vendored
49
app/src/types/protyle.d.ts
vendored
|
@ -1,15 +1,13 @@
|
|||
declare const echarts: {
|
||||
init(element: HTMLElement, theme?: string, options?: { width: number }): IEChart;
|
||||
dispose(element: Element): void;
|
||||
getInstanceById(id: string): { resize: () => void };
|
||||
};
|
||||
interface IABCJS {
|
||||
renderAbc(element: Element, text: string, options: { responsive: string }): void;
|
||||
}
|
||||
|
||||
declare const hljs: {
|
||||
highlight(text: string, options: { language?: string, ignoreIllegals: boolean }): { value: string };
|
||||
getLanguage(text: string): { name: string };
|
||||
};
|
||||
interface IViz {
|
||||
new(worker: { worker: Worker }): IViz;
|
||||
renderSVGElement: (code: string) => Promise<any>;
|
||||
}
|
||||
|
||||
interface IEChart {
|
||||
interface IEChartsInstance {
|
||||
setOption(option: any): void;
|
||||
|
||||
getZr(): any;
|
||||
|
@ -21,6 +19,37 @@ interface IEChart {
|
|||
resize(): void;
|
||||
}
|
||||
|
||||
interface IECharts {
|
||||
init(element: HTMLElement, theme?: string, options?: { width: number }): IEChartsInstance;
|
||||
dispose(element: Element): void;
|
||||
getInstanceById(id: string): { resize: () => void };
|
||||
}
|
||||
|
||||
interface IHLJS {
|
||||
highlight(text: string, options: { language?: string, ignoreIllegals: boolean }): { value: string };
|
||||
getLanguage(text: string): { name: string };
|
||||
listLanguages(): string[];
|
||||
}
|
||||
|
||||
interface IKaTeX {
|
||||
renderToString(math: string, option: {
|
||||
displayMode: boolean;
|
||||
output: string;
|
||||
macros: IObject;
|
||||
trust: boolean;
|
||||
strict: (errorCode: string) => "ignore" | "warn";
|
||||
}): string;
|
||||
}
|
||||
|
||||
interface IMermaid {
|
||||
initialize(options: any): void;
|
||||
init(options: any, element: Element): void;
|
||||
}
|
||||
|
||||
interface IPlantumlEncoder {
|
||||
encode(options: string): string;
|
||||
}
|
||||
|
||||
interface ILuteNode {
|
||||
TokensStr: () => string;
|
||||
__internal_object__: {
|
||||
|
|
Loading…
Add table
Reference in a new issue