Skip to content

Instantly share code, notes, and snippets.

@lorefnon
Last active April 24, 2019 18:22
Show Gist options
  • Save lorefnon/dccc263ad821164b6d2abb9222f90601 to your computer and use it in GitHub Desktop.
Save lorefnon/dccc263ad821164b6d2abb9222f90601 to your computer and use it in GitHub Desktop.
Markdown transformer to convert Code blocks to embedded (base64 encoded) images syntax highlighted by carbon.now.sh
{
"latest-preset": {
"t": "dracula",
"bg": "transparent",
"wt": "sharp",
"wc": true,
"fm": "Fira Code",
"fs": "11px",
"ln": false,
"ds": true,
"dsyoff": "20px",
"dsblur": "68px",
"wa": true,
"lh": "133%",
"pv": "5px",
"ph": "5px",
"si": false,
"wm": false,
"es": "1x",
"type": "png"
}
}
const remark = require("remark");
const path = require("path");
const fs = require("fs-extra");
const visit = require("unist-util-visit");
const crypto = require("crypto");
const exec = require("execa");
const sanitize = require("sanitize-filename");
const TMP_DIR = path.resolve("./tmp");
const main = () => {
const [inputFile, outputFile] = process.argv.slice(2);
remark()
.use(scrShot)
.process(fs.readFileSync(inputFile).toString(), (err, output) => {
if (err) {
console.error(err);
process.exit(1);
}
fs.writeFileSync(outputFile, output);
});
};
const scrShot = () => async tree => {
await fs.ensureDir(TMP_DIR);
const nodesToChange = [];
visit(tree, "code", node => {
nodesToChange.push({
node
});
});
for (const node of nodesToChange) {
await processNode(node);
}
// carbon api times out when there are many concurrent requests
// await Promise.all(nodesToChange.map(processNode));
};
const processNode = async ({ node }) => {
const code = node.value;
const snippetId = (
crypto
.createHash("sha1")
.update(code)
.digest("hex")
);
const targetFileName = snippetId;
const targetFilePath = path.join(TMP_DIR, `${targetFileName}.png`);
let imgData;
try {
imgData = await fs.readFile(targetFilePath);
} catch (e) {
if (e.code !== "ENOENT") throw e;
imgData = await getRemoteScreenshot(
snippetId,
node.lang || "txt",
code,
targetFilePath
);
}
node.type = "image";
node.url = `data:image/png;base64,${imgData.toString("base64")}`;
node.alt = "code screenshot";
};
const getRemoteScreenshot = async (snippetId, lang, code, targetFilePath) => {
const fileName = `${snippetId}.${lang || "txt"}`;
await fs.writeFile(path.resolve(TMP_DIR, fileName), code);
const { stdout, stderr } = await exec("node", [
require.resolve("carbon-now-cli/cli.js"),
path.join(TMP_DIR, fileName),
"--headless",
"--location",
TMP_DIR,
"--target",
snippetId,
"--preset",
"latest-preset"
]);
console.log("stdout:\n", stdout);
console.log("stderr:\n", stderr);
return fs.readFile(targetFilePath);
};
main();
{
"name": "mdpp",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"carbon-now-cli": "^1.4.0",
"execa": "^1.0.0",
"fs-extra": "^7.0.1",
"remark": "^10.0.1",
"sanitize-filename": "^1.6.1",
"unist-util-visit": "^1.4.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment