feat: Add a macro translator.

This commit is contained in:
Yaotian-Liu 2023-05-21 18:50:15 +08:00
parent 4cab4a02c4
commit e2662f15b0
No known key found for this signature in database
GPG key ID: 160A5464FF2FBA1F
2 changed files with 79 additions and 3 deletions

13
main.ts
View file

@ -8,9 +8,12 @@ import {
PseudocodeBlockInit,
BLOCK_NAME,
} from "src/setting";
import {
translateUnsupportedMacrosPerf,
checkTranslatedMacros,
} from "src/latex_translator";
import * as pseudocode from "pseudocode";
import * as katex from "katex";
export default class PseudocodePlugin extends Plugin {
settings: PseudocodeSettings;
@ -93,8 +96,12 @@ export default class PseudocodePlugin extends Plugin {
}
try {
katex.renderToString(this.preamble);
console.log("Preamble file loaded.");
this.preamble = translateUnsupportedMacrosPerf(this.preamble);
this.preamble = checkTranslatedMacros(this.preamble);
console.log("Loaded preamble:\n" + this.preamble);
console.log(
"Preamble file loaded. You can check the detail in console."
);
if (this.settings.preambleLoadedNotice) {
new Notice("Pseudocode Plugin: Preamble file loaded.");
}

69
src/latex_translator.ts Normal file
View file

@ -0,0 +1,69 @@
import * as katex from "katex";
export function translateUnsupportedMacros(input: string): string {
// handle \DeclarePairedDelimiter
let output = input.replace(
/\\DeclarePairedDelimiter\{(.*?)\}\{(.*?)\}\{(.*?)\}/g,
"\\newcommand{$1}[1]{\\left$2 #1 \\right$3}"
);
// handle \DeclareMathOperator
output = output.replace(
/\\DeclareMathOperator\*\{(.*?)\}\{(.*?)\}/g,
"\\newcommand{$1}{\\mathop{\\mathrm{$2}}}"
);
output = output.replace(
/\\DeclareMathOperator\{(.*?)\}\{(.*?)\}/g,
"\\newcommand{$1}{\\mathop{\\mathrm{$2}}}"
);
return output;
}
// This is a performance improvement for translateUnsupportedMacros
export function translateUnsupportedMacrosPerf(input: string): string {
const stripped = input
.replace(/(?<!\\)%.*/gm, "")
.split("\n")
.filter((line) => line.trim() !== "")
.join("\n");
return stripped.replace(
/(\\DeclarePairedDelimiter\{(.*?)\}\{(.*?)\}\{(.*?)\})|(\\DeclareMathOperator\*\{(.*?)\}\{(.*?)\})|(\\DeclareMathOperator\{(.*?)\}\{(.*?)\})/g,
(match, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) => {
if (p1) {
// It's a \DeclarePairedDelimiter
return `\\newcommand{${p2}}[1]{\\left${p3} #1 \\right${p4}}`;
} else if (p5) {
// It's a \DeclareMathOperator*
return `\\newcommand{${p6}}{\\mathop{\\mathrm{${p7}}}}`;
} else if (p8) {
// It's a \DeclareMathOperator
return `\\newcommand{${p9}}{\\mathop{\\mathrm{${p10}}}}`;
} else {
// This should never happen if the regex is correct
console.error(`Unexpected match: ${match}`);
return match;
}
}
);
}
export function checkTranslatedMacros(input: string): string {
const lines = input.split("\n");
for (let i = 0; i < lines.length; i++) {
try {
katex.renderToString(lines[i]);
} catch (error) {
if (
error instanceof katex.ParseError &&
/redefine/.test(error.message)
) {
lines[i] = lines[i].replace("\\newcommand", "\\renewcommand");
console.log(`Redefining ${lines[i]}`);
} else {
throw error;
}
}
}
return lines.join("\n");
}