diff --git a/frontend/code/components/codeBlock.ts b/frontend/code/components/codeBlock.ts index f53c1cbc..f55060f6 100644 --- a/frontend/code/components/codeBlock.ts +++ b/frontend/code/components/codeBlock.ts @@ -19,6 +19,14 @@ export type CodeBlockState = ComponentState & { display_controls?: boolean; }; +/// Contains additional aliases for languages that are not recognized by +/// highlight.js +const languageAliases: { [key: string]: string } = { + none: 'plaintext', + null: 'plaintext', + plain: 'plaintext', +}; + // Converts a `
` element into a code block. This is handled externally so // it can also be used by the markdown component. export function convertDivToCodeBlock( @@ -34,7 +42,7 @@ export function convertDivToCodeBlock(
-
+

     `;
 
     let headerElement = div.querySelector(
@@ -49,7 +57,12 @@ export function convertDivToCodeBlock(
         '.rio-code-block-copy-button'
     ) as HTMLButtonElement;
 
-    let codeElement = div.querySelector('code') as HTMLElement;
+    let preElement = div.querySelector('pre') as HTMLPreElement;
+
+    // Support additional language aliases
+    if (language !== null && languageAliases[language] !== undefined) {
+        language = languageAliases[language];
+    }
 
     // See if hljs recognizes the language
     if (language !== null && hljs.getLanguage(language) === undefined) {
@@ -65,7 +78,7 @@ export function convertDivToCodeBlock(
 
     if (language === null) {
         let hlResult = hljs.highlightAuto(sourceCode);
-        codeElement.innerHTML = hlResult.value;
+        preElement.innerHTML = hlResult.value;
 
         if (hlResult.language !== undefined) {
             hljsLanguage = hljs.getLanguage(hlResult.language);
@@ -75,7 +88,7 @@ export function convertDivToCodeBlock(
             language: language,
             ignoreIllegals: true,
         });
-        codeElement.innerHTML = hlResult.value;
+        preElement.innerHTML = hlResult.value;
 
         hljsLanguage = hljs.getLanguage(language);
     }
@@ -94,7 +107,7 @@ export function convertDivToCodeBlock(
         );
 
         copyButton.addEventListener('click', (event) => {
-            const codeToCopy = (codeElement as HTMLElement).textContent ?? '';
+            const codeToCopy = (preElement as HTMLPreElement).textContent ?? '';
 
             copyToClipboard(codeToCopy);
 
diff --git a/frontend/code/components/markdown.ts b/frontend/code/components/markdown.ts
index 00ef5127..51e1917c 100644
--- a/frontend/code/components/markdown.ts
+++ b/frontend/code/components/markdown.ts
@@ -47,20 +47,18 @@ function enhanceCodeBlocks(
     div: HTMLElement,
     defaultLanguage: string | null
 ): void {
-    const codeBlocks = div.querySelectorAll('pre code');
-    codeBlocks.forEach((rawCodeBlock) => {
-        rawCodeBlock = rawCodeBlock.parentElement!;
-
+    const codeBlocks = div.querySelectorAll('pre');
+    codeBlocks.forEach((preElement) => {
         // Create a new div to hold the code block
         let codeBlockElement = document.createElement('div');
-        rawCodeBlock.parentNode!.insertBefore(codeBlockElement, rawCodeBlock);
+        preElement.parentNode!.insertBefore(codeBlockElement, preElement);
 
         // Get the text content of the code block
-        let sourceCode = rawCodeBlock.textContent ?? '';
+        let sourceCode = preElement.textContent ?? '';
 
         // Was a language specified?
         let specifiedLanguage: string = defaultLanguage ?? '';
-        for (const cls of rawCodeBlock.classList) {
+        for (const cls of preElement.classList) {
             if (cls.startsWith('language-')) {
                 specifiedLanguage = cls.replace('language-', '');
                 break;
@@ -77,7 +75,7 @@ function enhanceCodeBlocks(
         );
 
         // Delete the original code block
-        rawCodeBlock.remove();
+        preElement.remove();
     });
 }
 
@@ -135,7 +133,7 @@ export class MarkdownComponent extends ComponentBase {
 
     createElement(): HTMLElement {
         const element = document.createElement('div');
-        element.classList.add('rio-markdown-view');
+        element.classList.add('rio-markdown');
         return element;
     }
 
diff --git a/frontend/css/style.scss b/frontend/css/style.scss
index abb5a373..02e88e9b 100644
--- a/frontend/css/style.scss
+++ b/frontend/css/style.scss
@@ -1178,7 +1178,7 @@ textarea:not(:placeholder-shown) ~ .rio-input-box-label,
 }
 
 // Markdown
-.rio-markdown-view {
+.rio-markdown {
     pointer-events: auto;
 
     color: var(--rio-local-text-color);
@@ -1311,6 +1311,8 @@ textarea:not(:placeholder-shown) ~ .rio-input-box-label,
 
     background: var(--rio-local-bg-variant);
     border-radius: var(--rio-global-corner-radius-small);
+
+    box-sizing: border-box;
 }
 
 .rio-code-block-header {
@@ -1318,9 +1320,10 @@ textarea:not(:placeholder-shown) ~ .rio-input-box-label,
     flex-direction: row;
     align-items: center;
     justify-content: space-between;
+    gap: 1rem;
 
     color: var(--rio-local-text-color);
-    gap: 1;
+    font-size: 0.8rem;
 }
 
 .rio-code-block-language {
@@ -1350,12 +1353,9 @@ textarea:not(:placeholder-shown) ~ .rio-input-box-label,
 
 .rio-code-block > pre {
     margin: 0;
-}
-
-.rio-code-block > code {
-    font-size: 1rem;
+    font-size: var(--rio-global-text-font-size);
+    font-family: $monospace-fonts;
     display: block;
-    padding: 0 var(--rio-padding) var(--rio-padding) var(--rio-padding);
 }
 
 // Link