Skip to content

Instantly share code, notes, and snippets.

@exceedsystem
Last active July 3, 2022 23:04
Show Gist options
  • Save exceedsystem/0d6095ea400eb4ab2bf6c3d3feefe1c0 to your computer and use it in GitHub Desktop.
Save exceedsystem/0d6095ea400eb4ab2bf6c3d3feefe1c0 to your computer and use it in GitHub Desktop.
An example of 'Markdown formatter' macro for VSCodeMacros extension
// [VSCode Macros] extension
// https://marketplace.visualstudio.com/items?itemName=EXCEEDSYSTEM.vscode-macros
// License:MIT
const vscode = require('vscode');
const remark = require('remark'); // Requires version 13 or above
const remarkParse = require('remark-parse');
const remarkStringify = require('remark-stringify');
const remarkGFM = require('remark-gfm');
const remarkFrontmatter = require('remark-frontmatter'); // Requires version 3 or above
module.exports.macroCommands = {
FormatMarkdown: {
no: 1,
func: formatMD,
},
};
function formatMD() {
const editor = vscode.window.activeTextEditor;
if (!editor) {
vscode.window.showWarningMessage('Editor not found.');
return;
}
const document = editor.document;
if (!document) {
vscode.window.showWarningMessage('Document not found.');
return;
}
if (document.languageId !== 'markdown') {
vscode.window.showWarningMessage(`This document type '${document.languageId}' is not supported.`);
return;
}
// Get east asian ambiguous characters
const eastAsianAmbiguous = Array.from('μ').map(s => s.codePointAt(0));
// Markdown formatting options(https://github.com/syntax-tree/mdast-util-to-markdown#formatting-options)
const remarksOptions = {
bullet: '-',
listItemIndent: 'one',
rule: '-'
};
const srcMarkdown = document.getText();
// Convert markdown text to the syntax tree
const mdNode = remark()
.use(remarkGFM)
.use(remarkParse)
.use(remarkFrontmatter)
.parse(srcMarkdown);
// Convert the syntax tree to markdown text
const dstMarkdown = remark()
.use(remarkGFM, {
// Calculate the number of characters in a cell
stringLength: (s) => {
let len = 0;
Array.from(s).forEach((elem) => {
let cpv;
const codePointValue = (cpv = elem.codePointAt(0)) !== undefined ? cpv : 0;
if (codePointValue <= 255 || (codePointValue >= 0xff61 && codePointValue <= 0xff9f || eastAsianAmbiguous.includes(codePointValue)))
++len;
else
// Double width
len += 2;
});
return len;
},
})
.use(remarkStringify, remarksOptions)
.use(remarkFrontmatter)
.stringify(mdNode);
if (srcMarkdown === dstMarkdown) {
vscode.window.showInformationMessage('Document is already formatted.');
return;
}
editor.edit((editBuilder) => {
// Replace with formatted markdown
const firstLine = document.lineAt(0);
const lastLine = document.lineAt(document.lineCount - 1);
editBuilder.replace(new vscode.Range(firstLine.range.start, lastLine.range.end), dstMarkdown);
vscode.window.showInformationMessage('Format completed.');
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment