From 1610939a44f28ba9f5f6511ef0a6c3339bbb95c4 Mon Sep 17 00:00:00 2001 From: lvjia Date: Sat, 9 Aug 2025 09:53:10 +0800 Subject: [PATCH] refactor: reuse regex patterns --- dist/mcfunction-highlight.min.js | 2 +- package-lock.json | 10 +++---- src/mcfunction-highlight-universal.js | 42 ++++++++++++++++++--------- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/dist/mcfunction-highlight.min.js b/dist/mcfunction-highlight.min.js index 328fe2c..16feb39 100644 --- a/dist/mcfunction-highlight.min.js +++ b/dist/mcfunction-highlight.min.js @@ -1 +1 @@ -!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.MCFunctionHighlight=n():e.MCFunctionHighlight=n()}(this,(()=>(()=>{var e={723:(e,n)=>{const t={highlight:e=>e.trimEnd().split("\n").map((e=>e.trim()?e.trim().startsWith("#")?`
${e}
`:`
${e=e.replace(/\b(execute|run)\b/g,(e=>`${e}`)).replace(/\b(align|anchored|as|at|facing|in|positioned|rotated|store|result|success)\b/g,(e=>`${e}`)).replace(/\b(if|unless)\b/g,(e=>`${e}`)).replace(/\b(advancement|agent|alwaysday|attribute|ban|ban-ip|banlist|bossbar|camera|camerashake|clear|clearspawnpoint|teleport|clone|connect|damage|data|datapack|daylock|debug|deop|difficulty|effect|enchant|event|experience|fill|fillbiome|fog|forceload|function|gamemode|gamerule|give|help|hud|immutableworld|inputpermission|item|jfr|kick|kill|list|locate|loot|me|mobevent|msg|music|op|particle|permission|place|playsound|recipe|reload|ride|say|schedule|scoreboard|setblock|setworldspawn|spawnpoint|spreadplayers|stop|stopsound|summon|tag|tell|tellraw|time|title|tp|transfer|weather|whitelist|xp|tick)\b/g,(e=>`${e}`)).replace(/@[apers](?:\[(?:[^\]]*(?:type|distance|limit|sort|x|y|z|dx|dy|dz|scores|tag|team|name|nbt|predicate|gamemode|level|advancements|nbt|rotation|pitch|yaw)=[^\]]*)*\])?/g,(e=>`${e}`)).replace(/(?:^|\s)([~^][-\d]*\.?\d*)/g,((e,n)=>e.replace(n,`${n}`))).replace(/\b(\d+(?:\.\.\d+)?)\b/g,(e=>`${e}`)).replace(/\b(true|false)\b/g,(e=>`${e}`)).replace(/\b(type|distance|limit|sort|scores|tag|team|name|nbt|predicate|gamemode|level|advancements|rotation|pitch|yaw|dx|dy|dz|x|y|z|sort|nearest|furthest|random|arbitrary|block|blocks|entity|score|matches|eyes|feet|dimension|storage|bossbar|scale)\b/g,(e=>`${e}`)).replace(/\b(overworld|the_nether|the_end)\b/g,(e=>`${e}`)).replace(/\b(announceAdvancements|blockExplosionDropDecay|commandBlockOutput|commandModificationBlockLimit|disableElytraMovementCheck|disablePlayerMovementCheck|disableRaids|doDaylightCycle|doEntityDrops|doFireTick|doImmediateRespawn|doInsomnia|doLimitedCrafting|doMobLoot|doMobSpawning|doPatrolSpawning|doTileDrops|doTraderSpawning|doVinesSpread|doWardenSpawning|doWeatherCycle|drowningDamage|fallDamage|fireDamage|freezeDamage|functionCommandLimit|keepInventory|maxCommandChainLength|mobGriefing|naturalRegeneration|playersSleepingPercentage|projectilesCanBreakBlocks|pvp|randomTickSpeed|recipesUnlock|respawnBlocksExplode|sendCommandFeedback|showBorderEffect|showCoordinates|showDaysPlayed|showDeathMessages|showRecipeMessages|showTags|spawnRadius|tntExplodes|tntExplosionDropDecay)\b/g,(e=>`${e}`)).replace(/\b(list|add|speed|glowing|true|remove|modify|get|set|reset|enable|operation|display|numberformat|setdisplay)\b/g,(e=>`${e}`))}
`:"
 
")).join(""),options:{autoUpdate:!0},configure(e){Object.assign(this.options,e)},init(){this.highlightAll(),this.options.autoUpdate&&this.observeDOM()},highlightAll(){"undefined"!=typeof document&&document.querySelectorAll("pre > code.language-mcfunction").forEach((e=>{this.highlightElement(e)}))},highlightElement(e){const n=e.textContent,t=this.highlight(n),o=document.createElement("div");o.className="mcfunction-viewer";const a=document.createElement("div");a.className="mcfunction-content",a.innerHTML=t,o.appendChild(a);const i=document.createElement("button");i.className="mcfunction-copy-button",i.textContent="复制",i.addEventListener("click",(()=>this.copyCode(n,i))),o.appendChild(i);const c=e.parentNode;c.innerHTML="",c.appendChild(o)},observeDOM(){if("undefined"!=typeof document){new MutationObserver((e=>{e.forEach((e=>{e.addedNodes.forEach((e=>{if(1===e.nodeType){e.querySelectorAll("pre > code.language-mcfunction").forEach((e=>this.highlightElement(e)))}}))}))})).observe(document.body,{childList:!0,subtree:!0})}},async copyCode(e,n){try{await navigator.clipboard.writeText(e),n.textContent="已复制!",n.classList.add("success"),setTimeout((()=>{n.textContent="复制",n.classList.remove("success")}),2e3)}catch(e){console.error("复制失败:",e),n.textContent="复制失败",setTimeout((()=>{n.textContent="复制"}),2e3)}},highlightWithWrapper(e){return`
${this.highlight(e)}
`},getCSS:()=>"\n.mcfunction-viewer {\n font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;\n background: #1e1e1e !important;\n color: #d4d4d4;\n text-shadow: 0 1px rgba(0, 0, 0, 0.3);\n text-align: left;\n white-space: pre;\n word-spacing: normal;\n word-break: normal;\n line-height: 1.5;\n tab-size: 4;\n hyphens: none;\n padding: 1em;\n margin: 0;\n overflow: hidden;\n border-radius: 0.3em;\n position: relative;\n display: flex;\n min-height: 50px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.mcfunction-content {\n overflow: auto;\n padding-right: 20px;\n flex: 1;\n min-width: 0;\n width: 100%;\n}\n\n.mcfunction-viewer .command { color: #ffaa00; font-weight: bold; }\n.mcfunction-viewer .selector { color: #55ffff; }\n.mcfunction-viewer .coordinates { color: #55ff55; }\n.mcfunction-viewer .string { color: #ff5555; }\n.mcfunction-viewer .comment { color: #7f7f7f; }\n.mcfunction-viewer .number { color: #55ff55; }\n.mcfunction-viewer .execute-modifier { color: #ff55ff; }\n.mcfunction-viewer .execute-condition { color: #ff5555; }\n.mcfunction-viewer .parameter { color: #55ffff; }\n.mcfunction-viewer .dimension { color: #55ffff; }\n.mcfunction-viewer .boolean { color: #ffaa00; }\n.mcfunction-viewer .gamerule {color:#7fffd4}\n\n/* 只在浏览器环境中显示复制按钮相关样式 */\n"+("undefined"!=typeof window?"\n.mcfunction-copy-button {\n position: sticky;\n right: 0.5em;\n top: 0.5em;\n height: fit-content;\n margin-left: 10px;\n flex-shrink: 0;\n padding: 0.4em 0.8em;\n background: #333;\n border: 1px solid #666;\n border-radius: 0.3em;\n color: #d4d4d4;\n font-size: 0.8em;\n cursor: pointer;\n opacity: 0;\n transition: opacity 0.2s;\n}\n\n.mcfunction-copy-button:hover {\n background: #444;\n}\n\n.mcfunction-copy-button.success {\n background: #28a745;\n border-color: #28a745;\n}\n\n.mcfunction-viewer:hover .mcfunction-copy-button {\n opacity: 1;\n}":"")};"undefined"!=typeof window&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>{t.init()})):t.init()),"undefined"==typeof window?e.exports&&(e.exports=t):window.MCFunctionHighlight=t,Object.defineProperty(n,"__esModule",{value:!0}),n.default=t}},n={};function t(o){var a=n[o];if(void 0!==a)return a.exports;var i=n[o]={exports:{}};return e[o](i,i.exports,t),i.exports}t.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return t.d(n,{a:n}),n},t.d=(e,n)=>{for(var o in n)t.o(n,o)&&!t.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:n[o]})},t.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n);var o={};return(()=>{"use strict";t.d(o,{default:()=>a});var e=t(723),n=t.n(e);"undefined"!=typeof window&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>n().init())):n().init());const a=n()})(),o=o.default})())); \ No newline at end of file +!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.MCFunctionHighlight=n():e.MCFunctionHighlight=n()}(this,(()=>(()=>{var e={723:(e,n)=>{const t=/\b(execute|run)\b/g,o=/\b(align|anchored|as|at|facing|in|positioned|rotated|store|result|success)\b/g,a=/\b(if|unless)\b/g,i=/\b(advancement|agent|alwaysday|attribute|ban|ban-ip|banlist|bossbar|camera|camerashake|clear|clearspawnpoint|teleport|clone|connect|damage|data|datapack|daylock|debug|deop|difficulty|effect|enchant|event|experience|fill|fillbiome|fog|forceload|function|gamemode|gamerule|give|help|hud|immutableworld|inputpermission|item|jfr|kick|kill|list|locate|loot|me|mobevent|msg|music|op|particle|permission|place|playsound|recipe|reload|ride|say|schedule|scoreboard|setblock|setworldspawn|spawnpoint|spreadplayers|stop|stopsound|summon|tag|tell|tellraw|time|title|tp|transfer|weather|whitelist|xp|tick)\b/g,c=/@[apers](?:\[(?:[^\]]*(?:type|distance|limit|sort|x|y|z|dx|dy|dz|scores|tag|team|name|nbt|predicate|gamemode|level|advancements|nbt|rotation|pitch|yaw)=[^\]]*)*\])?/g,r=/(?:^|\s)([~^][-\d]*\.?\d*)/g,s=/\b(\d+(?:\.\.\d+)?)\b/g,d=/\b(true|false)\b/g,l=/\b(type|distance|limit|sort|scores|tag|team|name|nbt|predicate|gamemode|level|advancements|rotation|pitch|yaw|dx|dy|dz|x|y|z|sort|nearest|furthest|random|arbitrary|block|blocks|entity|score|matches|eyes|feet|dimension|storage|bossbar|scale)\b/g,p=/\b(overworld|the_nether|the_end)\b/g,m=/\b(announceAdvancements|blockExplosionDropDecay|commandBlockOutput|commandModificationBlockLimit|disableElytraMovementCheck|disablePlayerMovementCheck|disableRaids|doDaylightCycle|doEntityDrops|doFireTick|doImmediateRespawn|doInsomnia|doLimitedCrafting|doMobLoot|doMobSpawning|doPatrolSpawning|doTileDrops|doTraderSpawning|doVinesSpread|doWardenSpawning|doWeatherCycle|drowningDamage|fallDamage|fireDamage|freezeDamage|functionCommandLimit|keepInventory|maxCommandChainLength|mobGriefing|naturalRegeneration|playersSleepingPercentage|projectilesCanBreakBlocks|pvp|randomTickSpeed|recipesUnlock|respawnBlocksExplode|sendCommandFeedback|showBorderEffect|showCoordinates|showDaysPlayed|showDeathMessages|showRecipeMessages|showTags|spawnRadius|tntExplodes|tntExplosionDropDecay)\b/g,f=/\b(list|add|speed|glowing|remove|modify|get|set|reset|enable|operation|display|numberformat|setdisplay)\b/g,u={highlight:e=>e.trimEnd().split("\n").map((e=>{const n=e.trim();return n?n.startsWith("#")?`
${e}
`:`
${e=e.replace(t,(e=>`${e}`)).replace(o,(e=>`${e}`)).replace(a,(e=>`${e}`)).replace(i,(e=>`${e}`)).replace(c,(e=>`${e}`)).replace(r,((e,n)=>e.replace(n,`${n}`))).replace(s,(e=>`${e}`)).replace(d,(e=>`${e}`)).replace(l,(e=>`${e}`)).replace(p,(e=>`${e}`)).replace(m,(e=>`${e}`)).replace(f,(e=>`${e}`))}
`:"
 
"})).join(""),options:{autoUpdate:!0},configure(e){Object.assign(this.options,e)},init(){this.highlightAll(),this.options.autoUpdate&&this.observeDOM()},highlightAll(){"undefined"!=typeof document&&document.querySelectorAll("pre > code.language-mcfunction").forEach((e=>{this.highlightElement(e)}))},highlightElement(e){const n=e.textContent,t=this.highlight(n),o=document.createElement("div");o.className="mcfunction-viewer";const a=document.createElement("div");a.className="mcfunction-content",a.innerHTML=t,o.appendChild(a);const i=document.createElement("button");i.className="mcfunction-copy-button",i.textContent="复制",i.addEventListener("click",(()=>this.copyCode(n,i))),o.appendChild(i);const c=e.parentNode;c.innerHTML="",c.appendChild(o)},observeDOM(){if("undefined"!=typeof document){new MutationObserver((e=>{e.forEach((e=>{e.addedNodes.forEach((e=>{if(1===e.nodeType){e.querySelectorAll("pre > code.language-mcfunction").forEach((e=>this.highlightElement(e)))}}))}))})).observe(document.body,{childList:!0,subtree:!0})}},async copyCode(e,n){try{await navigator.clipboard.writeText(e),n.textContent="已复制!",n.classList.add("success"),setTimeout((()=>{n.textContent="复制",n.classList.remove("success")}),2e3)}catch(e){console.error("复制失败:",e),n.textContent="复制失败",setTimeout((()=>{n.textContent="复制"}),2e3)}},highlightWithWrapper(e){return`
${this.highlight(e)}
`},getCSS:()=>"\n.mcfunction-viewer {\n font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;\n background: #1e1e1e !important;\n color: #d4d4d4;\n text-shadow: 0 1px rgba(0, 0, 0, 0.3);\n text-align: left;\n white-space: pre;\n word-spacing: normal;\n word-break: normal;\n line-height: 1.5;\n tab-size: 4;\n hyphens: none;\n padding: 1em;\n margin: 0;\n overflow: hidden;\n border-radius: 0.3em;\n position: relative;\n display: flex;\n min-height: 50px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.mcfunction-content {\n overflow: auto;\n padding-right: 20px;\n flex: 1;\n min-width: 0;\n width: 100%;\n}\n\n.mcfunction-viewer .command { color: #ffaa00; font-weight: bold; }\n.mcfunction-viewer .selector { color: #55ffff; }\n.mcfunction-viewer .coordinates { color: #55ff55; }\n.mcfunction-viewer .string { color: #ff5555; }\n.mcfunction-viewer .comment { color: #7f7f7f; }\n.mcfunction-viewer .number { color: #55ff55; }\n.mcfunction-viewer .execute-modifier { color: #ff55ff; }\n.mcfunction-viewer .execute-condition { color: #ff5555; }\n.mcfunction-viewer .parameter { color: #55ffff; }\n.mcfunction-viewer .dimension { color: #55ffff; }\n.mcfunction-viewer .boolean { color: #ffaa00; }\n.mcfunction-viewer .gamerule {color:#7fffd4}\n\n/* 只在浏览器环境中显示复制按钮相关样式 */\n"+("undefined"!=typeof window?"\n.mcfunction-copy-button {\n position: sticky;\n right: 0.5em;\n top: 0.5em;\n height: fit-content;\n margin-left: 10px;\n flex-shrink: 0;\n padding: 0.4em 0.8em;\n background: #333;\n border: 1px solid #666;\n border-radius: 0.3em;\n color: #d4d4d4;\n font-size: 0.8em;\n cursor: pointer;\n opacity: 0;\n transition: opacity 0.2s;\n}\n\n.mcfunction-copy-button:hover {\n background: #444;\n}\n\n.mcfunction-copy-button.success {\n background: #28a745;\n border-color: #28a745;\n}\n\n.mcfunction-viewer:hover .mcfunction-copy-button {\n opacity: 1;\n}":"")};"undefined"!=typeof window&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>{u.init()})):u.init()),"undefined"==typeof window?e.exports&&(e.exports=u):window.MCFunctionHighlight=u,Object.defineProperty(n,"__esModule",{value:!0}),n.default=u}},n={};function t(o){var a=n[o];if(void 0!==a)return a.exports;var i=n[o]={exports:{}};return e[o](i,i.exports,t),i.exports}t.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return t.d(n,{a:n}),n},t.d=(e,n)=>{for(var o in n)t.o(n,o)&&!t.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:n[o]})},t.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n);var o={};return(()=>{"use strict";t.d(o,{default:()=>a});var e=t(723),n=t.n(e);"undefined"!=typeof window&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>n().init())):n().init());const a=n()})(),o=o.default})())); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8d97099..f0755e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "mcfunction-highlight", - "version": "2.0.0", + "version": "3.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "mcfunction-highlight", - "version": "2.0.0", + "version": "3.1.0", "license": "MIT", "devDependencies": { "css-loader": "^7.1.2", @@ -1543,9 +1543,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { diff --git a/src/mcfunction-highlight-universal.js b/src/mcfunction-highlight-universal.js index 5187167..8e17331 100644 --- a/src/mcfunction-highlight-universal.js +++ b/src/mcfunction-highlight-universal.js @@ -1,50 +1,64 @@ +const EXECUTE_REGEX = /\b(execute|run)\b/g; +const EXECUTE_MODIFIER_REGEX = /\b(align|anchored|as|at|facing|in|positioned|rotated|store|result|success)\b/g; +const EXECUTE_CONDITION_REGEX = /\b(if|unless)\b/g; +const COMMAND_REGEX = /\b(advancement|agent|alwaysday|attribute|ban|ban-ip|banlist|bossbar|camera|camerashake|clear|clearspawnpoint|teleport|clone|connect|damage|data|datapack|daylock|debug|deop|difficulty|effect|enchant|event|experience|fill|fillbiome|fog|forceload|function|gamemode|gamerule|give|help|hud|immutableworld|inputpermission|item|jfr|kick|kill|list|locate|loot|me|mobevent|msg|music|op|particle|permission|place|playsound|recipe|reload|ride|say|schedule|scoreboard|setblock|setworldspawn|spawnpoint|spreadplayers|stop|stopsound|summon|tag|tell|tellraw|time|title|tp|transfer|weather|whitelist|xp|tick)\b/g; +const SELECTOR_REGEX = /@[apers](?:\[(?:[^\]]*(?:type|distance|limit|sort|x|y|z|dx|dy|dz|scores|tag|team|name|nbt|predicate|gamemode|level|advancements|nbt|rotation|pitch|yaw)=[^\]]*)*\])?/g; +const COORDINATE_REGEX = /(?:^|\s)([~^][-\d]*\.?\d*)/g; +const NUMBER_REGEX = /\b(\d+(?:\.\.\d+)?)\b/g; +const BOOLEAN_REGEX = /\b(true|false)\b/g; +const PARAMETER_REGEX = /\b(type|distance|limit|sort|scores|tag|team|name|nbt|predicate|gamemode|level|advancements|rotation|pitch|yaw|dx|dy|dz|x|y|z|sort|nearest|furthest|random|arbitrary|block|blocks|entity|score|matches|eyes|feet|dimension|storage|bossbar|scale)\b/g; +const DIMENSION_REGEX = /\b(overworld|the_nether|the_end)\b/g; +const GAMERULE_REGEX = /\b(announceAdvancements|blockExplosionDropDecay|commandBlockOutput|commandModificationBlockLimit|disableElytraMovementCheck|disablePlayerMovementCheck|disableRaids|doDaylightCycle|doEntityDrops|doFireTick|doImmediateRespawn|doInsomnia|doLimitedCrafting|doMobLoot|doMobSpawning|doPatrolSpawning|doTileDrops|doTraderSpawning|doVinesSpread|doWardenSpawning|doWeatherCycle|drowningDamage|fallDamage|fireDamage|freezeDamage|functionCommandLimit|keepInventory|maxCommandChainLength|mobGriefing|naturalRegeneration|playersSleepingPercentage|projectilesCanBreakBlocks|pvp|randomTickSpeed|recipesUnlock|respawnBlocksExplode|sendCommandFeedback|showBorderEffect|showCoordinates|showDaysPlayed|showDeathMessages|showRecipeMessages|showTags|spawnRadius|tntExplodes|tntExplosionDropDecay)\b/g; +const STRING_REGEX = /\b(list|add|speed|glowing|remove|modify|get|set|reset|enable|operation|display|numberformat|setdisplay)\b/g; + const MCFunctionHighlight = { highlight(code) { return code.trimEnd().split('\n').map(line => { - if (!line.trim()) { + const trimmed = line.trim(); + if (!trimmed) { return '
 
'; } - if (line.trim().startsWith('#')) { + if (trimmed.startsWith('#')) { return `
${line}
`; } line = line // execute子命令 - .replace(/\b(execute|run)\b/g, + .replace(EXECUTE_REGEX, match => `${match}`) // execute修饰子命令 - .replace(/\b(align|anchored|as|at|facing|in|positioned|rotated|store|result|success)\b/g, + .replace(EXECUTE_MODIFIER_REGEX, match => `${match}`) // execute条件子命令 - .replace(/\b(if|unless)\b/g, + .replace(EXECUTE_CONDITION_REGEX, match => `${match}`) // 其他命令 - .replace(/\b(advancement|agent|alwaysday|attribute|ban|ban-ip|banlist|bossbar|camera|camerashake|clear|clearspawnpoint|teleport|clone|connect|damage|data|datapack|daylock|debug|deop|difficulty|effect|enchant|event|experience|fill|fillbiome|fog|forceload|function|gamemode|gamerule|give|help|hud|immutableworld|inputpermission|item|jfr|kick|kill|list|locate|loot|me|mobevent|msg|music|op|particle|permission|place|playsound|recipe|reload|ride|say|schedule|scoreboard|setblock|setworldspawn|spawnpoint|spreadplayers|stop|stopsound|summon|tag|tell|tellraw|time|title|tp|transfer|weather|whitelist|xp|tick)\b/g, + .replace(COMMAND_REGEX, match => `${match}`) // 选择器 - .replace(/@[apers](?:\[(?:[^\]]*(?:type|distance|limit|sort|x|y|z|dx|dy|dz|scores|tag|team|name|nbt|predicate|gamemode|level|advancements|nbt|rotation|pitch|yaw)=[^\]]*)*\])?/g, + .replace(SELECTOR_REGEX, match => `${match}`) // 坐标 - .replace(/(?:^|\s)([~^][-\d]*\.?\d*)/g, + .replace(COORDINATE_REGEX, (match, coord) => match.replace(coord, `${coord}`)) // 数字和范围 - .replace(/\b(\d+(?:\.\.\d+)?)\b/g, + .replace(NUMBER_REGEX, match => `${match}`) // 布尔值 - .replace(/\b(true|false)\b/g, + .replace(BOOLEAN_REGEX, match => `${match}`) // 选择器参数和execute参数 - .replace(/\b(type|distance|limit|sort|scores|tag|team|name|nbt|predicate|gamemode|level|advancements|rotation|pitch|yaw|dx|dy|dz|x|y|z|sort|nearest|furthest|random|arbitrary|block|blocks|entity|score|matches|eyes|feet|dimension|storage|bossbar|scale)\b/g, + .replace(PARAMETER_REGEX, match => `${match}`) // 维度ID - .replace(/\b(overworld|the_nether|the_end)\b/g, + .replace(DIMENSION_REGEX, match => `${match}`) //游戏规则 - .replace(/\b(announceAdvancements|blockExplosionDropDecay|commandBlockOutput|commandModificationBlockLimit|disableElytraMovementCheck|disablePlayerMovementCheck|disableRaids|doDaylightCycle|doEntityDrops|doFireTick|doImmediateRespawn|doInsomnia|doLimitedCrafting|doMobLoot|doMobSpawning|doPatrolSpawning|doTileDrops|doTraderSpawning|doVinesSpread|doWardenSpawning|doWeatherCycle|drowningDamage|fallDamage|fireDamage|freezeDamage|functionCommandLimit|keepInventory|maxCommandChainLength|mobGriefing|naturalRegeneration|playersSleepingPercentage|projectilesCanBreakBlocks|pvp|randomTickSpeed|recipesUnlock|respawnBlocksExplode|sendCommandFeedback|showBorderEffect|showCoordinates|showDaysPlayed|showDeathMessages|showRecipeMessages|showTags|spawnRadius|tntExplodes|tntExplosionDropDecay)\b/g, + .replace(GAMERULE_REGEX, match => `${match}`) // 其他字符串 - .replace(/\b(list|add|speed|glowing|true|remove|modify|get|set|reset|enable|operation|display|numberformat|setdisplay)\b/g, + .replace(STRING_REGEX, match => `${match}`); return `
${line}
`;