feat: add skript + mcfunction highlightjs support (#4739)

* feat: add skript + mcfunction highlightjs support

* fix: lint

* fix: dep

* lint

---------

Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com>
This commit is contained in:
Calum H.
2025-11-08 02:24:08 +00:00
committed by GitHub
parent 6a6adb3480
commit b998c71337
11 changed files with 165 additions and 75 deletions

View File

@@ -0,0 +1,73 @@
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 { configuredXss, md } from '../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 const renderHighlightedString = (string) =>
configuredXss.process(
md({
highlight(str, lang) {
if (lang && hljs.getLanguage(lang)) {
try {
return hljs.highlight(str, { language: lang }).value
} catch {
/* empty */
}
}
return ''
},
}).render(string),
)

View File

@@ -0,0 +1,140 @@
import type { HLJSApi } from 'highlight.js'
/*
Language: Skript
Description: Skript language support for Minecraft server scripting
Website: https:
Category: scripting
*/
export default function (hljs: HLJSApi) {
const CONTROL_KEYWORDS = {
keyword: 'if else while loop return continue at stop cancel false true now',
built_in: 'parse do',
}
const ENTITIES = 'player players victim attacker sender loop-player shooter console'
const CONDITION_OPERATORS =
'contains has have is was were are does can cannot ' +
"hasn't haven't isn't wasn't weren't aren't doesn't can't"
return {
name: 'Skript',
aliases: ['sk'],
case_insensitive: true,
keywords: CONTROL_KEYWORDS,
contains: [
{
className: 'comment',
begin: '(?<!#)#(?!#)',
end: '$',
relevance: 0,
},
{
className: 'string',
begin: '"',
end: '"',
illegal: '\\n',
contains: [hljs.BACKSLASH_ESCAPE],
},
{
className: 'section',
begin: '\\bon\\s+',
end: ':',
excludeEnd: false,
keywords: 'on',
relevance: 10,
},
{
className: 'section',
begin: '\\bcommand\\s+/',
end: ':',
excludeEnd: false,
relevance: 10,
},
{
className: 'variable',
begin: '{',
end: '}',
contains: [
{
className: 'variable',
begin: ':+',
relevance: 0,
},
],
},
{
className: 'params',
begin: '<',
end: '>',
relevance: 5,
},
{
className: 'function',
begin: '\\b[a-zA-Z_][a-zA-Z0-9_]*(?=\\()',
relevance: 0,
},
{
className: 'variable',
begin: '\\b(loop|event)-[a-zA-Z]+\\b',
relevance: 5,
},
{
className: 'number',
variants: [
{ begin: '\\b\\d+(\\.\\d+)?\\s+(tick|second|minute|hour|day)s?\\b' },
{ begin: '\\ba\\s+(tick|second|minute|hour|day)s?\\b' },
{ begin: '\\b(minecraft|mc|real|rl|irl)\\s+(tick|second|minute|hour|day)s?\\b' },
],
relevance: 0,
},
hljs.NUMBER_MODE,
{
className: 'built_in',
begin: '\\b(' + ENTITIES + ')\\b',
relevance: 0,
},
{
className: 'built_in',
begin: "(uuid\\s+of|'s\\s+uuid|location\\s+of|'s\\s+location)",
relevance: 0,
},
{
className: 'operator',
begin: '\\b(' + CONDITION_OPERATORS.split(' ').join('|') + ')\\b',
relevance: 0,
},
{
className: 'operator',
begin: '::?',
relevance: 0,
},
{
className: 'literal',
begin: '\\b(true|false)\\b',
relevance: 0,
},
{
className: 'keyword',
begin: '\\b(stop|cancel|halt|enable|disable|trigger|server)\\b',
relevance: 5,
},
],
}
}