KatexPhysics
もともとのマクロ定義をコピペして利用できた。
ket, bra, braketはkatexもともとのマクロが使いたいので消している
preview:
https://gyazo.com/e3a02a2e0f040f3864950f02976843ee
code:macros.js
function popNextArg(ctx) {
return ctx.consumeArgs(1)0.reverse().map(t => t.text).join(""); }
function getSqureParameter(ctx) {
while (ctx.future().text === " ") {
ctx.popToken();
}
let parameter = "";
if (ctx.future().text === "[") {
ctx.popToken();
while (true) {
const ch = ctx.popToken().text;
if (ch === "]") {
break;
} else if (ch === "EOF") {
throw new Error("Expecting ]");
}
parameter += ch;
}
}
return parameter;
}
function isAlt(ctx) {
while (ctx.future().text === " ") {
ctx.popToken();
}
if (ctx.future().text === "*") {
ctx.popToken();
return true;
}
return false;
}
const braces = {
"(": ")",
"{": "}",
"\\{": "\\}",
"|": "|",
};
const evalBraces = {
"(": "|",
"[": "|",
"{": "}",
};
const matrixBraces = {
"(": ")",
"{": "}",
"\\{": "\\}",
"|": "|"
};
const isDigit = /^\d+$/;
const dd = (n, f) => "\\dd+ n + "{" + f + "}";
const pd = (n, f) => "\\pd+ n + "{" + f + "}";
export const macros = {
"\\qty"(ctx) {
const start = ctx.popToken().text;
if (typeof end === "undefined") {
throw new Error("Expecting opening delimeters after \\qty");
}
expr.push(start === "{" ? "\\{" : start);
let opened = 0;
while (true) {
const next = ctx.popToken().text;
if (next === "EOF") {
throw new Error("Expecting closing delimeters " + end + " after \\mqty");
} else if (next !== end) {
expr.push(next);
if (next === start) {
++opened;
}
} else if (opened > 0) {
expr.push(next);
--opened;
} else {
// end
expr.push("\\right");
expr.push(end === "}" ? "\\}" : next);
break;
}
}
return expr.join(" ");
},
"\\abs": "\\qty|{#1}|",
"\\eval"(ctx) {
const start = ctx.popToken().text;
let end = evalBracesstart; if (typeof end === "undefined") {
throw new Error("Expecting opening delimeters after \\eval");
}
expr.push(start === "{" ? "." : start);
let opened = 0;
while (true) {
const next = ctx.popToken().text;
if (next === "EOF") {
throw new Error("Expecting " + end + " after \\eval");
} else if (next !== end) {
expr.push(next);
if (next === start) {
++opened;
}
} else if (end === "}" && opened > 0) {
expr.push(next);
--opened;
} else {
// end
expr.push("\\rule{0px}{1.2em}\\right|");
break;
}
}
return expr.join(" ");
},
"\\dd"(ctx) {
const n = getSqureParameter(ctx);
let op = "\\mathrm{d}";
if (n && !isDigit.test(n) || n > 1) {
op += "^{" + n + "}";
}
if (ctx.future().text !== "{") {
return op;
}
try {
const ch = popNextArg(ctx);
return "\\mathop{}\\!" + op + "{" + ch + "}";
} catch (e) {
return op;
}
},
"\\pd"(ctx) {
const n = getSqureParameter(ctx);
let op = "\\partial";
if (n && !isDigit.test(n) || n > 1) {
op += "^{" + n + "}";
}
if (ctx.future().text !== "{") {
return op;
}
try {
const ch = popNextArg(ctx);
return "\\mathop{}\\!" + op + "{" + ch + "}";
} catch (e) {
return op;
}
},
"\\dv"(ctx) {
const n = getSqureParameter(ctx);
const fn = popNextArg(ctx);
while (ctx.future().text === " ") {
ctx.popToken();
}
if (ctx.future().text !== "{") {
return "\\frac{\\dd^{" + n + "}}{" + dd(1, fn) + "^{" + n + "}}";
}
let variable;
try {
variable = popNextArg(ctx);
} catch (e) {}
return "\\frac{" + dd(n, fn) + "}{" + dd(1, variable) + "^{" + n + "}}";
},
"\\pdv"(ctx) {
const n = getSqureParameter(ctx);
const fn = popNextArg(ctx);
if (n) {
while (ctx.future().text === " ") {
ctx.popToken();
}
if (ctx.future().text !== "{") {
return "\\frac{\\pd^{" + n + "}}{" + pd(1, fn) + "^{" + n + "}}";
}
let variable;
try {
variable = popNextArg(ctx);
} catch (e) {}
return "\\frac{" + pd(n, fn) + "}{" + pd(1, variable) + "^{" + n + "}}";
}
const args = [];
while (true) {
while (ctx.future().text === " ") {
ctx.popToken();
}
if (ctx.future().text !== "{") {
break;
}
try {
args.push(popNextArg(ctx));
} catch (e) {
break;
}
}
if (args.length === 0) {
return "\\frac{\\partial}{" + pd(args.length, fn) + "}"
}
return "\\frac{" + pd(args.length, fn) + "}{" +
args.map(arg => pd(1, arg)).join("") + "}"
},
"\\ketbra"(ctx) {
const a = popNextArg(ctx);
try {
expr.push(popNextArg(ctx));
} catch (e) {
expr.push(a);
}
expr.push("}\\right|");
return expr.join(" ");
},
"\\expval"(ctx) {
const a = popNextArg(ctx);
while (ctx.future().text === " ") {
ctx.popToken();
}
if (ctx.future().text !== "{") {
return "\\left<{" + a + "}\\right>";
}
const b = popNextArg(ctx);
return "\\left<{" + b + "}\\middle|{" + a + "}\\middle|{" + b + "}\\right>";
},
"\\matrixel"(ctx) {
const a, b, c = ctx.consumeArgs(3).map(arg => arg.reverse().map(t => t.text).join("")); return "\\left<{" + a + "}\\middle|{" + b + "}\\middle|{" + c + "}\\right>";
},
"\\mqty"(ctx) {
const start = ctx.popToken().text;
const end = matrixBracesstart; if (typeof end === "undefined") {
throw new Error("Expecting opening delimeters after \\qty");
}
expr.push(start === "{" ? "\\{" : start);
expr.push("\\begin{matrix}");
let opened = 0;
while (true) {
const next = ctx.popToken().text;
if (next === "EOF") {
throw new Error("Expecting closing delimeters " + end + " after \\mqty");
} else if (next !== end) {
expr.push(next);
if (next === start) {
++opened;
}
} else if (opened > 0) {
expr.push(next);
--opened;
} else {
// end
expr.push("\\end{matrix}\\right");
expr.push(end === "}" ? "\\}" : next);
break;
}
}
return expr.join(" ");
},
"\\mdet": "\\left|\\begin{matrix}#1\\end{matrix}\\right|",
"\\dmat"(ctx) {
const fill = getSqureParameter(ctx);
const elements = popNextArg(ctx).split(",");
const lines = [];
for (let i = 0; i < elements.length; ++i) {
let line = new Array(elements.length).fill(fill);
lines.push(line.map(el => "{" + el + "}").join("&"));
}
return lines.join("\\\\");
},
"\\admat"(ctx) {
const fill = getSqureParameter(ctx);
const elements = popNextArg(ctx).split(",");
const lines = [];
for (let i = 0; i < elements.length; ++i) {
let line = new Array(elements.length).fill(fill);
lines.push(line.map(el => "{" + el + "}").join("&"));
}
return lines.join("\\\\");
},
"\\imat"(ctx) {
const n = parseInt(popNextArg(ctx));
if (isNaN(n)) {
throw new Error("Expecting integers as the parameter of \\imat");
}
return "\\dmat0{" + new Array(n).fill(1).join(",") + "}"; },
"\\xmat"(ctx) {
const labeled = isAlt(ctx);
popNextArg(ctx),
parseInt(popNextArg(ctx)),
parseInt(popNextArg(ctx)),
];
if (isNaN(n) || isNaN(m)) {
throw new Error("Expecting integers as the second and third parameter of \\xmat");
}
if (!labeled || (n === 1 && m === 1)) {
return new Array(n).fill(new Array(m).fill(x).join("&")).join("\\\\");
}
const matrix = [];
for (let i = 1; i <= n; ++i) {
const row = [];
for (let j = 1; j <= m; ++j) {
let label = "" + (n > 1 ? i : "") + (m > 1 ? j : "");
row.push(x + "_{" + label + "}")
}
matrix.push(row);
}
return matrix.map(row => row.join(",")).join("\\\\")
},
"\\qc": ",\\quad",
"\\qq": ctx => (isAlt(ctx) ? "" : "\\quad") + "\\text{" + popNextArg() + "}\\quad",
"\\qcc": ctx => (isAlt(ctx) ? "" : "\\quad") + "\\text{c.c.}\\quad",
"\\qif": ctx => (isAlt(ctx) ? "" : "\\quad") + "\\text{if}\\quad",
}