import hljs from 'highlight.js/lib/core' // Configs import gradle from 'highlight.js/lib/languages/gradle' // Coding import groovy from 'highlight.js/lib/languages/groovy' import ini from 'highlight.js/lib/languages/ini' import java from 'highlight.js/lib/languages/java' // Scripting import javascript from 'highlight.js/lib/languages/javascript' import json from 'highlight.js/lib/languages/json' import kotlin from 'highlight.js/lib/languages/kotlin' import lua from 'highlight.js/lib/languages/lua' import properties from 'highlight.js/lib/languages/properties' import python from 'highlight.js/lib/languages/python' import scala from 'highlight.js/lib/languages/scala' import xml from 'highlight.js/lib/languages/xml' import yaml from 'highlight.js/lib/languages/yaml' import mcfunction from 'highlightjs-mcfunction' import type { ComponentRenderFn } from '@comark/html/render' import type { ElementNode } from 'comark' import { createModrinthHtmlRenderer, getFenceCodeText, getFenceLanguage } from '../markdown/parse' import skript from './skript' /* REGISTRATION */ // Scripting hljs.registerLanguage('javascript', javascript) hljs.registerLanguage('python', python) hljs.registerLanguage('lua', lua) hljs.registerLanguage('skript', skript) hljs.registerLanguage('mcfunction', mcfunction) // Coding hljs.registerLanguage('java', java) hljs.registerLanguage('kotlin', kotlin) hljs.registerLanguage('scala', scala) hljs.registerLanguage('groovy', groovy) // Configs hljs.registerLanguage('gradle', gradle) hljs.registerLanguage('json', json) hljs.registerLanguage('ini', ini) hljs.registerLanguage('yaml', yaml) hljs.registerLanguage('xml', xml) hljs.registerLanguage('properties', properties) /* ALIASES */ // Scripting hljs.registerAliases(['js'], { languageName: 'javascript' }) hljs.registerAliases(['py'], { languageName: 'python' }) hljs.registerAliases(['sk'], { languageName: 'skript' }) hljs.registerAliases(['command'], { languageName: 'mcfunction' }) hljs.registerAliases(['kubejs'], { languageName: 'javascript' }) // Coding hljs.registerAliases(['kt'], { languageName: 'kotlin' }) // Configs hljs.registerAliases(['json5'], { languageName: 'json' }) hljs.registerAliases(['toml'], { languageName: 'ini' }) hljs.registerAliases(['yml'], { languageName: 'yaml' }) hljs.registerAliases(['html', 'htm', 'xhtml', 'mcui', 'fxml'], { languageName: 'xml' }) export { hljs } function escapeHtml(value: string): string { return value.replace(/[&<>"']/g, (char) => { switch (char) { case '&': return '&' case '<': return '<' case '>': return '>' case '"': return '"' default: return ''' } }) } const highlightedPreComponent: ComponentRenderFn = (node) => { const preNode = node as ElementNode const codeText = getFenceCodeText(preNode) const language = getFenceLanguage(preNode) let inner: string let className: string | undefined if (language && hljs.getLanguage(language)) { try { inner = hljs.highlight(codeText, { language }).value className = `hljs language-${language}` } catch { inner = escapeHtml(codeText) className = `language-${language}` } } else { inner = escapeHtml(codeText) className = language ? `language-${language}` : undefined } return `
${inner}`
}
export const renderHighlightedString = createModrinthHtmlRenderer({ pre: highlightedPreComponent })
export const highlightCodeLines = (code: string, language: string): string[] => {
if (!code) return []
if (!hljs.getLanguage(language)) {
return code.split('\n')
}
try {
const highlighted = hljs.highlight(code, { language }).value
const openTags: string[] = []
const processedHtml = highlighted.replace(/(]+>)|(<\/span>)|(\n)/g, (match) => {
if (match === '\n') {
return ''.repeat(openTags.length) + '\n' + openTags.join('')
}
if (match === '') {
openTags.pop()
} else {
openTags.push(match)
}
return match
})
return processedHtml.split('\n')
} catch {
return code.split('\n')
}
}