mume-with-litvis
Version:
Fork of mume with added http://litvis.org/
222 lines • 10.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.runCodeChunks = exports.runCodeChunk = exports.renderCodeBlock = void 0;
const code_chunk_1 = require("../code-chunk");
const toc_1 = require("../toc");
const utility_1 = require("../utility");
function enhance($, codeChunksData, renderOptions, runOptions) {
return __awaiter(this, void 0, void 0, function* () {
const asyncFunctions = [];
const arrayOfCodeChunkData = [];
$('[data-role="codeBlock"]').each((i, container) => {
const $container = $(container);
if ($container.data("executor")) {
return;
}
const normalizedInfo = $container.data("normalizedInfo");
if (!normalizedInfo.attributes["cmd"]) {
return;
}
$container.data("executor", "fenced-code-chunks");
asyncFunctions.push(renderCodeBlock($container, normalizedInfo, $, codeChunksData, arrayOfCodeChunkData, renderOptions, runOptions));
});
yield Promise.all(asyncFunctions);
});
}
exports.default = enhance;
function renderCodeBlock($container, normalizedInfo, $, codeChunksData, arrayOfCodeChunkData, renderOptions, runOptions) {
return __awaiter(this, void 0, void 0, function* () {
const code = $container.text();
const id = normalizedInfo.attributes["id"] ||
"code-chunk-id-" + arrayOfCodeChunkData.length;
const cmd = (0, utility_1.extractCommandFromBlockInfo)(normalizedInfo);
const isJavascript = ["js", "javascript"].indexOf(cmd) !== -1;
const $codeAndOutputWrapper = $('<div class="code-chunk"></div>');
$codeAndOutputWrapper.attr("data-id", id);
$codeAndOutputWrapper.attr("data-cmd", cmd);
if (isJavascript) {
$codeAndOutputWrapper.attr("data-code", code);
}
$container.replaceWith($codeAndOutputWrapper);
const $codeWrapper = $('<div class="input-div"/>');
$codeWrapper.append($container);
$codeAndOutputWrapper.append($codeWrapper);
let codeChunkData = codeChunksData[id];
const prev = arrayOfCodeChunkData.length
? arrayOfCodeChunkData[arrayOfCodeChunkData.length - 1].id
: "";
if (!codeChunkData) {
codeChunkData = {
id,
code,
normalizedInfo,
result: "",
plainResult: "",
running: false,
prev,
next: null,
};
codeChunksData[id] = codeChunkData;
}
else {
codeChunkData.code = code;
codeChunkData.normalizedInfo = normalizedInfo;
codeChunkData.prev = prev;
}
if (prev && codeChunksData[prev]) {
codeChunksData[prev].next = id;
}
// this line has to be put above the `if` statement.
arrayOfCodeChunkData.push(codeChunkData);
if (renderOptions.triggeredBySave &&
normalizedInfo.attributes["run_on_save"]) {
yield runCodeChunk(id, codeChunksData, runOptions);
}
let result = codeChunkData.result;
// element attribute
if (!result && codeChunkData.normalizedInfo.attributes["element"]) {
result = codeChunkData.normalizedInfo.attributes["element"];
codeChunkData.result = result;
}
if (codeChunkData.running) {
$codeAndOutputWrapper.addClass("running");
}
const statusDiv = `<div class="status">running...</div>`;
const buttonGroup = '<div class="btn-group"><div class="run-btn btn"><span>▶︎</span></div><div class="run-all-btn btn">all</div></div>';
let outputDiv = `<div class="output-div">${result}</div>`;
// check javascript code chunk
if (!renderOptions.isForPreview && isJavascript) {
outputDiv += `<script>${code}</script>`;
result = codeChunkData.normalizedInfo.attributes["element"] || "";
}
$codeWrapper.append(buttonGroup);
$codeWrapper.append(statusDiv);
normalizedInfo.attributes["output_first"] === true
? $codeAndOutputWrapper.prepend(outputDiv)
: $codeAndOutputWrapper.append(outputDiv);
});
}
exports.renderCodeBlock = renderCodeBlock;
function runCodeChunk(id, codeChunksData, runOptions) {
return __awaiter(this, void 0, void 0, function* () {
const { headings, enableScriptExecution, filePath, fileDirectoryPath, latexEngine, modifySource, parseMD, } = runOptions;
const codeChunkData = codeChunksData[id];
if (!codeChunkData || codeChunkData.running) {
return "";
}
const combinedCodeAsArray = [codeChunkData.code];
let patentCodeChunkData = codeChunkData;
while (patentCodeChunkData.normalizedInfo.attributes["continue"]) {
let parentId = patentCodeChunkData.normalizedInfo.attributes["continue"];
if (parentId === true) {
parentId = patentCodeChunkData.prev;
}
patentCodeChunkData = codeChunksData[parentId];
if (!patentCodeChunkData) {
break;
}
combinedCodeAsArray.unshift(patentCodeChunkData.code);
}
const code = combinedCodeAsArray.join("\n");
const cmd = (0, utility_1.extractCommandFromBlockInfo)(codeChunkData.normalizedInfo);
codeChunkData.running = true;
let result;
let outputFormat = "text";
let blockModifiesSource = codeChunkData.normalizedInfo.attributes["modify_source"];
try {
const normalizedAttributes = codeChunkData.normalizedInfo.attributes;
if (cmd === "toc") {
// toc code chunk. <= this is a special code chunk.
const tocObject = (0, toc_1.toc)(headings, {
ordered: normalizedAttributes["ordered_list"],
depthFrom: normalizedAttributes["depth_from"],
depthTo: normalizedAttributes["depth_to"],
tab: normalizedAttributes["tab"] || " ",
ignoreLink: normalizedAttributes["ignore_link"],
});
result = tocObject.content;
outputFormat = "markdown";
blockModifiesSource = true;
}
else {
// common code chunk
// I put this line here because some code chunks like `toc` still need to be run.
if (!enableScriptExecution) {
return ""; // code chunk is disabled.
}
result = yield (0, code_chunk_1.run)(code, fileDirectoryPath, cmd, codeChunkData.normalizedInfo.attributes, latexEngine);
}
codeChunkData.plainResult = result;
if (blockModifiesSource &&
"code_chunk_offset" in codeChunkData.normalizedInfo.attributes) {
codeChunkData.result = "";
return modifySource(codeChunkData, result, filePath);
}
// set output format for a few special cases
if (cmd.match(/(la)?tex/) || cmd === "pdflatex") {
outputFormat = "markdown";
}
else if (cmd.match(/python/) &&
(normalizedAttributes["matplotlib"] || normalizedAttributes["mpl"])) {
outputFormat = "markdown";
}
else if (codeChunkData.normalizedInfo.attributes["output"]) {
outputFormat = codeChunkData.normalizedInfo.attributes["output"];
}
if (!result) {
// do nothing
result = "";
}
else if (outputFormat === "html") {
result = result;
}
else if (outputFormat === "png") {
const base64 = new Buffer(result).toString("base64");
result = `<img src="data:image/png;charset=utf-8;base64,${base64}">`;
}
else if (outputFormat === "markdown") {
const { html } = yield parseMD(result, {
useRelativeFilePath: true,
isForPreview: false,
hideFrontMatter: true,
});
result = html;
}
else if (outputFormat === "none") {
result = "";
}
else {
result = `<pre class="language-text">${result}</pre>`;
}
}
catch (error) {
result = `<pre class="language-text">${error}</pre>`;
}
codeChunkData.result = result; // save result.
codeChunkData.running = false;
return result;
});
}
exports.runCodeChunk = runCodeChunk;
function runCodeChunks(codeChunksData, runOptions) {
return __awaiter(this, void 0, void 0, function* () {
const asyncFunctions = [];
for (const id in codeChunksData) {
if (codeChunksData.hasOwnProperty(id)) {
asyncFunctions.push(runCodeChunk(id, codeChunksData, runOptions));
}
}
return Promise.all(asyncFunctions);
});
}
exports.runCodeChunks = runCodeChunks;
//# sourceMappingURL=fenced-code-chunks.js.map