Skip to content

Instantly share code, notes, and snippets.

@pedrovhb
Last active August 13, 2024 15:38
Show Gist options
  • Save pedrovhb/4693d04dbb967262944ad9ff2e89e6a6 to your computer and use it in GitHub Desktop.
Save pedrovhb/4693d04dbb967262944ad9ff2e89e6a6 to your computer and use it in GitHub Desktop.
CSS Highlights API syntax highlighting code custom element
<div><div>
<script type="module">
import { LitElement, html, css } from 'https://esm.sh/lit';
import "https://esm.sh/[email protected]";
class HlCode extends LitElement {
static properties = {
lang: { type: String }
};
static styles = css`
pre {
background-color: #f4f4f4;
padding: 1em;
border-radius: 5px;
overflow-x: auto;
}
code {
font-family: 'Consolas', 'Monaco', 'Andale Mono', 'Ubuntu Mono', monospace;
}
::highlight(syntax-highlight-keyword) { color: #07a; }
::highlight(syntax-highlight-function) { color: #DD4A68; }
::highlight(syntax-highlight-string) { color: #690; }
::highlight(syntax-highlight-punctuation) { color: #999; }
::highlight(syntax-highlight-operator) { color: #9a6e3a; }
::highlight(syntax-highlight-comment) { color: slategray; }
`;
render() {
return html`
<pre><code id="codeBlock"><slot></slot></code></pre>
`;
}
firstUpdated() {
this.updateComplete.then(() => {
this.highlightCode();
});
}
highlightCode() {
const codeBlock = this.shadowRoot.querySelector("#codeBlock");
const code = this.textContent.trim();
if (codeBlock && window.CSS && CSS.highlights) {
const highlighters = {};
const language = Prism.languages[this.lang] || Prism.languages.javascript;
const tokens = Prism.tokenize(code, language);
console.log('Code:', code);
console.log('Tokens:', tokens);
codeBlock.textContent = code;
let currentPosition = 0;
tokens.forEach(token => {
const content = typeof token === 'string' ? token : token.content;
const type = typeof token === 'string' ? 'text' : token.type;
if (!highlighters[type]) {
highlighters[type] = new Highlight();
}
if (codeBlock.firstChild) {
const range = new Range();
range.setStart(codeBlock.firstChild, currentPosition);
range.setEnd(codeBlock.firstChild, currentPosition + content.length);
highlighters[type].add(range);
}
currentPosition += content.length;
});
Object.entries(highlighters).forEach(([type, highlighter]) => {
CSS.highlights.set(`syntax-highlight-${type}`, highlighter);
});
console.log('Highlighting complete');
} else {
console.error("codeBlock not found in shadow DOM or CSS.highlights not supported");
}
}
}
customElements.define('hl-code', HlCode);
</script>
<hl-code lang="python">def foo() -&gt; int:
return 42</hl-code>
</div></div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment