mume-with-litvis
Version:
Fork of mume with added http://litvis.org/
589 lines (588 loc) • 19.1 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveBuildPathForWebview = exports.Function = exports.extractCommandFromBlockInfo = exports.loadDependency = exports.allowUnsafe = exports.uploadImage = exports.configs = exports.removeFileProtocol = exports.addFileProtocol = exports.useExternalAddFileProtocolFunction = exports.isArrayEqual = exports.getParserConfig = exports.getExtensionConfig = exports.getKaTeXConfig = exports.getMathJaxConfig = exports.defaultKaTeXConfig = exports.defaultMathjaxConfig = exports.getMermaidConfig = exports.getConfigPath = exports.getGlobalStyles = exports.extensionDirectoryPath = exports.openFile = exports.execFile = exports.tempOpen = exports.write = exports.writeFile = exports.readFile = exports.parseYAML = exports.sleep = exports.unescapeString = exports.escapeString = void 0;
const child_process = require("child_process");
const fs = require("fs");
const jsYAML = require("js-yaml");
const less = require("less");
const os = require("os");
const path = require("path");
const vm = require("vm");
const temp = require("temp");
temp.track();
const TAGS_TO_REPLACE = {
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'",
"/": "/",
"\\": "\",
};
const TAGS_TO_REPLACE_REVERSE = {
"&": "&",
"<": "<",
">": ">",
""": '"',
"'": "'",
"'": "'",
"/": "/",
"\": "\\",
};
function escapeString(str = "") {
return str.replace(/[&<>"'\/\\]/g, (tag) => TAGS_TO_REPLACE[tag] || tag);
}
exports.escapeString = escapeString;
function unescapeString(str = "") {
return str.replace(/\&(amp|lt|gt|quot|apos|\#x27|\#x2F|\#x5C)\;/g, (whole) => TAGS_TO_REPLACE_REVERSE[whole] || whole);
}
exports.unescapeString = unescapeString;
/**
* Do nothing and sleep for `ms` milliseconds
* @param ms
*/
function sleep(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
return resolve();
}, ms);
});
}
exports.sleep = sleep;
function parseYAML(yaml = "") {
// YAML doesn't work well with front-matter
/*
try {
return YAML.parse(yaml)
} catch(error) {
return {}
}
*/
if (yaml.startsWith("---")) {
yaml = yaml
.trim()
.replace(/^---\r?\n/, "")
.replace(/\r?\n---$/, "");
}
try {
return jsYAML.safeLoad(yaml);
}
catch (error) {
return {};
}
}
exports.parseYAML = parseYAML;
function readFile(file, options) {
return new Promise((resolve, reject) => {
fs.readFile(file, options, (error, text) => {
if (error) {
return reject(error.toString());
}
else {
return resolve(text.toString());
}
});
});
}
exports.readFile = readFile;
function writeFile(file, text, options) {
return new Promise((resolve, reject) => {
fs.writeFile(file, text, options, (error) => {
if (error) {
return reject(error.toString());
}
else {
return resolve();
}
});
});
}
exports.writeFile = writeFile;
function write(fd, text) {
return new Promise((resolve, reject) => {
fs.write(fd, text, (error) => {
if (error) {
return reject(error.toString());
}
else {
return resolve();
}
});
});
}
exports.write = write;
function tempOpen(options) {
return new Promise((resolve, reject) => {
temp.open(options, (error, info) => {
if (error) {
return reject(error.toString());
}
else {
return resolve(info);
}
});
});
}
exports.tempOpen = tempOpen;
function execFile(file, args, options) {
return new Promise((resolve, reject) => {
child_process.execFile(file, args, options, (error, stdout, stderr) => {
if (error) {
return reject(error.toString());
}
else if (stderr) {
return reject(stderr);
}
else {
return resolve(stdout);
}
});
});
}
exports.execFile = execFile;
/**
* open html file in browser or open pdf file in reader ... etc
* @param filePath
*/
function openFile(filePath) {
if (process.platform === "win32") {
if (filePath.match(/^[a-zA-Z]:\\/)) {
// C:\ like url.
filePath = "file:///" + filePath;
}
if (filePath.startsWith("file:///")) {
return child_process.execFile("explorer.exe", [filePath]);
}
else {
return child_process.exec(`start ${filePath}`);
}
}
else if (process.platform === "darwin") {
child_process.execFile("open", [filePath]);
}
else {
child_process.execFile("xdg-open", [filePath]);
}
}
exports.openFile = openFile;
/**
* get the directory path of this extension.
*/
exports.extensionDirectoryPath = path.resolve(__dirname, "../../");
/**
* compile ~/.mumi/style.less and return 'css' content.
*/
function getGlobalStyles(configPath) {
return __awaiter(this, void 0, void 0, function* () {
const globalLessFilePath = configPath
? path.resolve(configPath, "./style.less")
: path.resolve(getConfigPath(), "./style.less");
let fileContent;
try {
fileContent = yield readFile(globalLessFilePath, { encoding: "utf-8" });
}
catch (e) {
// create style.less file
fileContent = `
/* Please visit the URL below for more information: */
/* https://shd101wyy.github.io/markdown-preview-enhanced/#/customize-css */
.markdown-preview.markdown-preview {
// modify your style here
// eg: background-color: blue;
}
`;
yield writeFile(globalLessFilePath, fileContent, { encoding: "utf-8" });
}
return yield new Promise((resolve, reject) => {
less.render(fileContent, { paths: [path.dirname(globalLessFilePath)] }, (error, output) => {
if (error) {
return resolve(`html body:before {
content: "Failed to compile \`style.less\`. ${error}" !important;
padding: 2em !important;
}
.mume.mume { display: none !important; }`);
}
else {
return resolve(output.css || "");
}
});
});
});
}
exports.getGlobalStyles = getGlobalStyles;
/**
* Get default config path
* @
*/
function getConfigPath() {
const oldDefault = path.resolve(os.homedir(), "./.mume");
// For compatibility, use the old directory if either it exists
// or the user is on windows
if (fs.existsSync(oldDefault) || process.platform === "win32") {
return oldDefault;
}
else {
// Calculate new default
if (typeof process.env.XDG_CONFIG_HOME === "string" &&
process.env.XDG_CONFIG_HOME !== "") {
return path.resolve(process.env.XDG_CONFIG_HOME, "./mume");
}
else {
return path.resolve(os.homedir(), "./.local/state/mume");
}
}
}
exports.getConfigPath = getConfigPath;
/**
* load ~/.config/mume/mermaid_config.js file.
*/
function getMermaidConfig(configPath) {
return __awaiter(this, void 0, void 0, function* () {
const mermaidConfigPath = configPath
? path.resolve(configPath, "./mermaid_config.js")
: path.resolve(getConfigPath(), "./mermaid_config.js");
let mermaidConfig;
if (fs.existsSync(mermaidConfigPath)) {
try {
mermaidConfig = yield readFile(mermaidConfigPath, { encoding: "utf-8" });
}
catch (e) {
mermaidConfig = `MERMAID_CONFIG = {startOnLoad: false}`;
}
}
else {
const fileContent = `// config mermaid init call
// http://knsv.github.io/mermaid/#configuration
//
// You can edit the 'MERMAID_CONFIG' variable below.
MERMAID_CONFIG = {
startOnLoad: false
}
`;
yield writeFile(mermaidConfigPath, fileContent, { encoding: "utf-8" });
mermaidConfig = `MERMAID_CONFIG = {startOnLoad: false}`;
}
return mermaidConfig;
});
}
exports.getMermaidConfig = getMermaidConfig;
exports.defaultMathjaxConfig = {
"extensions": ["tex2jax.js"],
"jax": ["input/TeX", "output/HTML-CSS"],
"messageStyle": "none",
"tex2jax": {
processEnvironments: false,
processEscapes: true,
},
"TeX": {
extensions: [
"AMSmath.js",
"AMSsymbols.js",
"noErrors.js",
"noUndefined.js",
],
},
"HTML-CSS": { availableFonts: ["TeX"] },
};
exports.defaultKaTeXConfig = {
macros: {},
};
/**
* load ~/.config/mume/mathjax_config.js file.
*/
function getMathJaxConfig(configPath) {
return __awaiter(this, void 0, void 0, function* () {
const mathjaxConfigPath = configPath
? path.resolve(configPath, "./mathjax_config.js")
: path.resolve(getConfigPath(), "./mathjax_config.js");
let mathjaxConfig;
if (fs.existsSync(mathjaxConfigPath)) {
try {
delete require.cache[mathjaxConfigPath]; // return uncached
mathjaxConfig = require(mathjaxConfigPath);
}
catch (e) {
mathjaxConfig = exports.defaultMathjaxConfig;
}
}
else {
const fileContent = `
module.exports = {
extensions: ['tex2jax.js'],
jax: ['input/TeX','output/HTML-CSS'],
messageStyle: 'none',
tex2jax: {
processEnvironments: false,
processEscapes: true
},
TeX: {
extensions: ['AMSmath.js', 'AMSsymbols.js', 'noErrors.js', 'noUndefined.js']
},
'HTML-CSS': { availableFonts: ['TeX'] }
}
`;
yield writeFile(mathjaxConfigPath, fileContent, { encoding: "utf-8" });
mathjaxConfig = exports.defaultMathjaxConfig;
}
return mathjaxConfig;
});
}
exports.getMathJaxConfig = getMathJaxConfig;
/**
* load ~/.config/mume/katex_config.js file
*/
function getKaTeXConfig(configPath) {
return __awaiter(this, void 0, void 0, function* () {
const katexConfigPath = configPath
? path.resolve(configPath, "./katex_config.js")
: path.resolve(getConfigPath(), "./katex_config.js");
let katexConfig;
if (fs.existsSync(katexConfigPath)) {
try {
delete require.cache[katexConfigPath]; // return uncached
katexConfig = require(katexConfigPath);
}
catch (e) {
katexConfig = exports.defaultKaTeXConfig;
}
}
else {
const fileContent = `
module.exports = {
macros: {}
}`;
yield writeFile(katexConfigPath, fileContent, { encoding: "utf-8" });
katexConfig = exports.defaultKaTeXConfig;
}
return katexConfig;
});
}
exports.getKaTeXConfig = getKaTeXConfig;
function getExtensionConfig(configPath) {
return __awaiter(this, void 0, void 0, function* () {
const extensionConfigFilePath = configPath
? path.resolve(configPath, "./config.json")
: path.resolve(getConfigPath(), "./config.json");
let config;
if (fs.existsSync(extensionConfigFilePath)) {
try {
delete require.cache[extensionConfigFilePath]; // return uncached
config = require(extensionConfigFilePath);
}
catch (error) {
config = { error };
}
}
else {
config = {};
yield writeFile(extensionConfigFilePath, "{}", { encoding: "utf-8" });
}
return config;
});
}
exports.getExtensionConfig = getExtensionConfig;
function getParserConfig(configPath) {
return __awaiter(this, void 0, void 0, function* () {
const parserConfigPath = configPath
? path.resolve(configPath, "./parser.js")
: path.resolve(getConfigPath(), "./parser.js");
let parserConfig;
if (fs.existsSync(parserConfigPath)) {
try {
delete require.cache[parserConfigPath]; // return uncached
parserConfig = require(parserConfigPath);
}
catch (error) {
parserConfig = {};
}
}
else {
const template = `module.exports = {
onWillParseMarkdown: function(markdown) {
return new Promise((resolve, reject)=> {
return resolve(markdown)
})
},
onDidParseMarkdown: function(html, {cheerio}) {
return new Promise((resolve, reject)=> {
return resolve(html)
})
},
onWillTransformMarkdown: function (markdown) {
return new Promise((resolve, reject) => {
return resolve(markdown);
});
},
onDidTransformMarkdown: function (markdown) {
return new Promise((resolve, reject) => {
return resolve(markdown);
});
}
}`;
yield writeFile(parserConfigPath, template, { encoding: "utf-8" });
parserConfig = {};
}
return parserConfig;
});
}
exports.getParserConfig = getParserConfig;
/**
* Check whether two arrays are equal
* @param x
* @param y
*/
function isArrayEqual(x, y) {
if (x.length !== y.length) {
return false;
}
for (let i = 0; i < x.length; i++) {
if (x[i] !== y[i]) {
return false;
}
}
return true;
}
exports.isArrayEqual = isArrayEqual;
let _externalAddFileProtocolFunction = null;
function useExternalAddFileProtocolFunction(func) {
_externalAddFileProtocolFunction = func;
}
exports.useExternalAddFileProtocolFunction = useExternalAddFileProtocolFunction;
/**
* Add file:/// to file path
* If it's for VSCode preview, add vscode-resource:/// to file path
* @param filePath
*/
function addFileProtocol(filePath, vscodePreviewPanel) {
if (_externalAddFileProtocolFunction) {
return _externalAddFileProtocolFunction(filePath, vscodePreviewPanel);
}
else {
if (!filePath.startsWith("file://")) {
filePath = "file:///" + filePath;
}
filePath = filePath.replace(/^file\:\/+/, "file:///");
}
return filePath;
}
exports.addFileProtocol = addFileProtocol;
/**
* Remove file:// from file path
* @param filePath
*/
function removeFileProtocol(filePath) {
// See https://regex101.com/r/YlpEur/8/
// - "file://///a///b//c/d" ---> "a///b//c/d"
// - "vscode-resource://///file///a///b//c/d" ---> "file///a///b//c/d"
const regex = /^(?:(?:file|(vscode)-(?:webview-)?resource|vscode--resource):\/+)(.*)/m;
return filePath.replace(regex, (m, isVSCode, rest) => {
if (isVSCode) {
// For vscode urls -> Remove host: `file///C:/a/b/c` -> `C:/a/b/c`
rest = rest.replace(/^file\/+/, "");
}
if (process.platform !== "win32" && !rest.startsWith("/")) {
// On Linux platform, add a slash at the front
return "/" + rest;
}
else {
return rest;
}
});
}
exports.removeFileProtocol = removeFileProtocol;
/**
* style.less,
* mathjax_config.js,
* mermaid_config.js
* config.json
*
* files
*/
// @ts-ignore
exports.configs = {
globalStyle: "",
mathjaxConfig: exports.defaultMathjaxConfig,
katexConfig: exports.defaultKaTeXConfig,
mermaidConfig: "MERMAID_CONFIG = {startOnLoad: false}",
parserConfig: {},
config: {},
};
var image_uploader_1 = require("./image-uploader");
Object.defineProperty(exports, "uploadImage", { enumerable: true, get: function () { return image_uploader_1.uploadImage; } });
let originalEval = global.eval;
let originalFunction = global.Function;
let numberOfActiveOverrides = 0;
function allowUnsafe(fn) {
if (numberOfActiveOverrides === 0) {
originalEval = global.eval;
originalFunction = global.Function;
}
try {
numberOfActiveOverrides += 1;
global.eval = (source) => {
vm.runInThisContext(source);
};
return fn();
}
finally {
numberOfActiveOverrides -= 1;
if (numberOfActiveOverrides === 0) {
global.eval = originalEval;
global.Function = originalFunction;
}
}
}
exports.allowUnsafe = allowUnsafe;
const loadDependency = (dependencyPath) => allowUnsafe(() => {
// Unsetting global.module prevents libraries like vega-lite from calling require(), which does not work
const prevModule = global.module;
global.module = undefined;
const result = require(path.resolve(exports.extensionDirectoryPath, "dependencies", dependencyPath));
global.module = prevModule;
return result;
});
exports.loadDependency = loadDependency;
const extractCommandFromBlockInfo = (info) => info.attributes["cmd"] === true ? info.language : info.attributes["cmd"];
exports.extractCommandFromBlockInfo = extractCommandFromBlockInfo;
function Function(...args) {
let body = "";
const paramLists = [];
if (args.length) {
body = arguments[args.length - 1];
for (let i = 0; i < args.length - 1; i++) {
paramLists.push(args[i]);
}
}
const params = [];
for (let j = 0, len = paramLists.length; j < len; j++) {
let paramList = paramLists[j];
if (typeof paramList === "string") {
paramList = paramList.split(/\s*,\s*/);
}
params.push.apply(params, paramList);
}
return vm.runInThisContext(`
(function(${params.join(", ")}) {
${body}
})
`);
}
exports.Function = Function;
Function.prototype = global.Function.prototype;
const resolveBuildPathForWebview = (libraryName, buildPathForWebView) => {
const buildPathForNode = require.resolve(libraryName).replace(/\\/g, "/");
const indexOfLibraryName = buildPathForNode.indexOf(libraryName + "/");
const libraryPath = buildPathForNode.substring(0, indexOfLibraryName + libraryName.length);
return path.resolve(libraryPath, buildPathForWebView);
};
exports.resolveBuildPathForWebview = resolveBuildPathForWebview;
//# sourceMappingURL=utility.js.map