I am using highlight.js to render code snippets on this blog system. However, the official pack of highlight.js does not have Bicep as one of the languages. To add support for the Bicep language in highlight.js, you need to implement a Bicep language definition module. Below are the detailed steps and code examples.
Bicep Language Features
Bicep is a declarative, Azure-oriented Infrastructure-as-Code language. Its main features include:
- Keywords:
resource
,module
,param
,var
,output
,targetScope
,for
,in
,if
,existing
,import
- Types:
string
,int
,bool
,object
,array
,any
- Comments: // single-line comment, /* ... */ multi-line comment
- Strings: single quotes
'...'
and double quotes"..."
highlight.js Language Definition
The language definitions for highlight.js are usually as follows:
export default function(hljs) {
return {
name: 'Bicep',
keywords: { ... },
contains: [ ... ]
};
}
You can refer to this example of the cmake
language definition here: https://github.com/highlightjs/highlight.js/blob/main/src/languages/cmake.js
Let's create a file with name highlight.bicep.js
export default function (hljs) {
return {
name: 'Bicep',
keywords: {
keyword:
'resource module param var output targetScope for in if existing import',
type:
'string int bool object array any',
literal:
'true false null'
},
contains: [
hljs.COMMENT('//', '$'),
hljs.COMMENT('/\\*', '\\*/'),
{
className: 'string',
variants: [
hljs.QUOTE_STRING_MODE,
hljs.APOS_STRING_MODE
]
},
{
className: 'number',
begin: '\\b\\d+(\\.\\d+)?\\b'
}
]
};
}
Register Bicep Language and Example Usage
To register Bicep language, call hljs.registerLanguage('bicep', bicep)
before rendering your code.
import bicep from './highlight.bicep.js';
hljs.registerLanguage('bicep', bicep);
hljs.highlightAll();
You can refer to the official document here: https://highlightjs.readthedocs.io/en/latest/api.html#registerlanguage
In my case, my blog use a slightly complicated way to render code in my blog post.
import bicep from '../3rd/highlight.bicep.js'
export function renderCodeHighlighter() {
const pres = document.querySelectorAll('pre');
pres.forEach(pre => {
// Find <pre> that doesn't have a <code> inside it.
if (!pre.querySelector('code')) {
const code = document.createElement('code');
while (pre.firstChild) {
code.appendChild(pre.firstChild);
}
pre.appendChild(code);
}
// For code that can't be automatically detected, fall back to use XML
if (pre.classList.contains('language-markup')) {
pre.querySelector('code').classList.add('lang-xml');
}
});
hljs.registerLanguage('bicep', bicep);
const codeBlocks = document.querySelectorAll('pre code');
codeBlocks.forEach(block => {
hljs.highlightElement(block);
});
}
That's all. Now we can test the example code:
<pre><code class="bicep">
param location string = resourceGroup().location
resource storage 'Microsoft.Storage/storageAccounts@2022-09-01' = {
name: 'mystorage'
location: location
}
</code></pre>
If everything goes well, you will see this result:
param location string = resourceGroup().location
resource storage 'Microsoft.Storage/storageAccounts@2022-09-01' = {
name: 'mystorage'
location: location
}
Comments