// assets/js/hooks/code_block_hook.js import { codeToHtml } from "shiki"; const CodeBlockHook = { mounted() { const code = this.el.dataset.code; const language = this.el.dataset.language; const highlightedLines = JSON.parse( this.el.dataset.highlightedLines || "[]", ); console.log(code); console.log("language", language); const lines = code.split("\n"); // Convert line numbers to decorations const decorations = highlightedLines .map((line) => { // Convert to 0-based index and ensure valid line number const lineIndex = line - 1; if (lineIndex < 0 || lineIndex >= lines.length) return null; // Get the actual line length const lineLength = lines[lineIndex].length; return { // Line numbers are 0-indexed start: { line: lineIndex, character: 0 }, end: { line: lineIndex, character: lineLength }, properties: { // Apply both background color and a class for flexibility class: "highlight", style: "background-color: rgba(200,200,255,0.1);", }, }; }) .filter(Boolean); // Remove any null entries from invalid line numbers codeToHtml(code, { lang: language, theme: "catppuccin-mocha", decorations, }).then((html) => { console.log(html); // Replace the code content while preserving the pre/code structure const tempDiv = document.createElement("div"); tempDiv.innerHTML = html; const codeContent = tempDiv.querySelector("code"); if (codeContent) { this.el.querySelector("code").innerHTML = codeContent.innerHTML; } }); }, }; export default CodeBlockHook;