Home > other >  Format a code block in any language using nodejs
Format a code block in any language using nodejs

Time:10-31

I have code blocks that are fetched from a database, which could be any language: JSON, TS, JS, HTML, CSS, etc.

snippets.each(x => {
  x.code //<-- want to apply a simple indention/formatting here
})

All the text comes with a broken indent/formatting that going to be used as code snippets. Here are some examples:

HTML

<main role="main" >
<p style="margin-bottom: 2rem;">
<a href>text</a>
</p>
</main>

JS:

function example1(el: HTMLInputElement) {
if(x) {
...
}
return el;
}

I want to indent all the code blocks like that so they look readable. For example:

HTML

<main role="main" >
  <p style="margin-bottom: 2rem;">
    <a href>text</a>
 </p>
</main>

JS:

function example1(el: HTMLInputElement) {
  if(x) {
     ...
  }
  return el;
}

I wonder how would you do that?

I currently searched for a solution using Prettier or ESLint but haven't found yet how to use any of these just for that simple use case.

The code block language could be unknown, so it must work regardless of language.

CodePudding user response:

I was able to do this by combining vscode-languagedetection and the Prettier API.

vscode-languagedetection uses different programming language names than Prettier (ex: 'js' vs 'babel'), so you need to keep an conversion table langs.

const prettier = require("prettier");
const { ModelOperations } = require('@vscode/vscode-languagedetection');

const model = new ModelOperations();

async function formatCode(code) {
    const langPreds = await model.runModel(code);
    const lang = langPreds[0].languageId;
    const langs = {js: 'babel', html: 'html'}; // edit to convert vscode names to prettier parsers
    return prettier.format(code, { semi: false, parser: langs[lang] });
}


(async () => {
    const html = `
    <div role="main" >
    <p style="margin-bottom: 2rem;">
    <a href>text</a>
    </p>
    </div>
    `;

    const js = `
    function example1(el: HTMLInputElement) {
    if(x) {
    console.log('test')
    }
    return el;
    }
    `;
    
    console.log(await formatCode(html));
    console.log(await formatCode(js));
})()

Output:

<div role="main" >
  <p style="margin-bottom: 2rem">
    <a href>text</a>
  </p>
</div>

function example1(el: HTMLInputElement) {
  if (x) {
    console.log("test")
  }
  return el
}

If the the code block has escaped characters in it, you should unescape the code block before passing it to the function. This way, vs-languagedetection won't get confused. Once the code block has been formatted, it is OK to re-escape it.

  • Related