将 HTML 格式转换为 Mobile Legends 的 BBCode 格式
Converting HTML format to the BBCode format of Mobile Legends
我目前正在为游戏 Mobile Legends 开发一款富有创意的游戏内文本应用程序。该应用程序可以更改您在游戏中聊天时使用的文本颜色。还有其他添加,如粗体、斜体、下划线和删除线,最终输出为代码供您输入。该应用程序旨在用户友好且易于使用。但是,我在创意方面遇到了麻烦。
站点: https://mlcolor.netlify.app/
我使用 execcommand
制作了自己的富编辑器。我需要一个将 HTML 格式(富编辑器生成的)转换为 Mobile Legends 文本格式的解决方案。
Mobile Legends 格式
与HTML相同。它使用方括号 [b]Hello World[/b]
而不是 <b>Hello World</b>
这些是Mobile Legends中的格式,与HTML非常相似:
粗体:[b]Hello World[/b]
斜体:[i]Hello World[/i]
下划线:[u]Hello World[/u]
删除线:[s]Hello World[/s]
foreColor: [FF0000]Hello World
它使用十六进制代码。
问题
如何转换此代码(示例输出):
Hello World!
<b><i><u><strike>Hello World!</strike></u></i></b>
在此:
[b][i][u][s]Hello World![/b][/i][/s]
我的解决方案
我使用了一种使用.replace(/<b>/g,'[b]')
的方法。但是,如果格式变得太复杂,替换标签就更难了。代码变得复杂并且有很多属性。
复杂格式示例:
Lorem ipsum dolor sit amet.
<span style="font-family: "Open Sans", Arial, sans-serif; font-size: 14px; text-align: justify; background-color: rgb(255, 255, 255);"><span style="text-decoration: underline;"><font color="#a9fcd4"><i>Lo</i><b>rem</b></font></span> <i style="text-decoration: underline;"><font color="#0000cc">ipsu<b>m</b></font></i> <b style="text-decoration: underline;"><i><font color="#cc00cc">dolor</font></i></b> <u><font color="#cccc00">sit</font></u> <strike><font color="#cc00cc"><b>amet</b><i>.</i></font></strike></span><br>
Disclaimer: I’m not a professional coder by any means so I apologize
for any amateur mistakes. Coding is just my spare time hobby and I
decided to make this app for the Mobile Legends community since I play
the game too and wanted to decorate my bio and chat text.
您应该使用 DOM 解析器解析输入。然后递归地遍历 DOM ,并检查每个访问节点的样式以确定应指定哪些标签和颜色。这是它的工作原理:
function parse(html) {
let appliedColor = "000000";
function parseNode(inheritedStyles, inheritedColor, node) {
// Base case: a plain text node:
if (node.nodeType === 3) {
if (inheritedColor !== appliedColor && node.nodeValue.trim()) {
appliedColor = inheritedColor;
return `[${appliedColor}]${node.nodeValue}`;
}
return node.nodeValue;
}
// Transfer color HTML attribute to style attribute:
if (node.nodeName === "FONT" && node.color) node.style.color = node.color;
// Get relevant styles of this node
let {color, textDecorationLine, fontWeight, fontStyle} = node.style;
color = color || inheritedColor;
// Determine U,S,B,I:
let styles = {
u: inheritedStyles.u || node.nodeName === "U" || textDecorationLine.includes("underline"),
s: inheritedStyles.s || node.nodeName === "STRIKE" || textDecorationLine.includes("through"),
b: inheritedStyles.b || node.nodeName === "B" || fontWeight.includes("bold") || +fontWeight >= 700,
i: inheritedStyles.i || node.nodeName === "I" || fontStyle.includes("italic")
};
// Deal with color
if (color.slice(0,4) === "rgb(") {
color = color.match(/\d+/g).map(dec => (+dec).toString(16).padStart(2, "0")).join("").toUpperCase();
}
// Apply recursion to parse the child nodes
let res = Array.from(node.childNodes, parseNode.bind(null, styles, color)).join("");
// Wrap the content inside the necessary [] tags
for (let prop in styles) {
if (styles[prop] !== !!inheritedStyles[prop]) res = `[${prop}]${res}[\/${prop}]`;
}
return res;
}
return parseNode({}, "000000", new DOMParser().parseFromString(html, "text/html").body);
}
// Demo
let html = `<span style="font-family: "Open Sans", Arial, sans-serif; font-size: 14px; text-align: justify; background-color: rgb(255, 255, 255);"><span style="text-decoration: underline;"><font color="#a9fcd4"><i>Lo<\/i><b>rem<\/b><\/font><\/span> <i style="text-decoration: underline;"><font color="#0000cc">ipsu<b>m<\/b><\/font><\/i> <b style="text-decoration: underline;"><i><font color="#cc00cc">dolor<\/font><\/i><\/b> <u><font color="#cccc00">sit<\/font><\/u> <strike><font color="#cc00cc"><b>amet<\/b><i>.<\/i><\/font><\/strike><\/span><br>`;
console.log(parse(html));
我目前正在为游戏 Mobile Legends 开发一款富有创意的游戏内文本应用程序。该应用程序可以更改您在游戏中聊天时使用的文本颜色。还有其他添加,如粗体、斜体、下划线和删除线,最终输出为代码供您输入。该应用程序旨在用户友好且易于使用。但是,我在创意方面遇到了麻烦。
站点: https://mlcolor.netlify.app/
我使用 execcommand
制作了自己的富编辑器。我需要一个将 HTML 格式(富编辑器生成的)转换为 Mobile Legends 文本格式的解决方案。
Mobile Legends 格式
与HTML相同。它使用方括号 [b]Hello World[/b]
<b>Hello World</b>
这些是Mobile Legends中的格式,与HTML非常相似:
粗体:[b]Hello World[/b]
斜体:[i]Hello World[/i]
下划线:[u]Hello World[/u]
删除线:[s]Hello World[/s]
foreColor: [FF0000]Hello World
它使用十六进制代码。
问题
如何转换此代码(示例输出):
Hello World!
<b><i><u><strike>Hello World!</strike></u></i></b>
在此:
[b][i][u][s]Hello World![/b][/i][/s]
我的解决方案
我使用了一种使用.replace(/<b>/g,'[b]')
的方法。但是,如果格式变得太复杂,替换标签就更难了。代码变得复杂并且有很多属性。
复杂格式示例:
Lorem ipsum dolor sit
amet.
<span style="font-family: "Open Sans", Arial, sans-serif; font-size: 14px; text-align: justify; background-color: rgb(255, 255, 255);"><span style="text-decoration: underline;"><font color="#a9fcd4"><i>Lo</i><b>rem</b></font></span> <i style="text-decoration: underline;"><font color="#0000cc">ipsu<b>m</b></font></i> <b style="text-decoration: underline;"><i><font color="#cc00cc">dolor</font></i></b> <u><font color="#cccc00">sit</font></u> <strike><font color="#cc00cc"><b>amet</b><i>.</i></font></strike></span><br>
Disclaimer: I’m not a professional coder by any means so I apologize for any amateur mistakes. Coding is just my spare time hobby and I decided to make this app for the Mobile Legends community since I play the game too and wanted to decorate my bio and chat text.
您应该使用 DOM 解析器解析输入。然后递归地遍历 DOM ,并检查每个访问节点的样式以确定应指定哪些标签和颜色。这是它的工作原理:
function parse(html) {
let appliedColor = "000000";
function parseNode(inheritedStyles, inheritedColor, node) {
// Base case: a plain text node:
if (node.nodeType === 3) {
if (inheritedColor !== appliedColor && node.nodeValue.trim()) {
appliedColor = inheritedColor;
return `[${appliedColor}]${node.nodeValue}`;
}
return node.nodeValue;
}
// Transfer color HTML attribute to style attribute:
if (node.nodeName === "FONT" && node.color) node.style.color = node.color;
// Get relevant styles of this node
let {color, textDecorationLine, fontWeight, fontStyle} = node.style;
color = color || inheritedColor;
// Determine U,S,B,I:
let styles = {
u: inheritedStyles.u || node.nodeName === "U" || textDecorationLine.includes("underline"),
s: inheritedStyles.s || node.nodeName === "STRIKE" || textDecorationLine.includes("through"),
b: inheritedStyles.b || node.nodeName === "B" || fontWeight.includes("bold") || +fontWeight >= 700,
i: inheritedStyles.i || node.nodeName === "I" || fontStyle.includes("italic")
};
// Deal with color
if (color.slice(0,4) === "rgb(") {
color = color.match(/\d+/g).map(dec => (+dec).toString(16).padStart(2, "0")).join("").toUpperCase();
}
// Apply recursion to parse the child nodes
let res = Array.from(node.childNodes, parseNode.bind(null, styles, color)).join("");
// Wrap the content inside the necessary [] tags
for (let prop in styles) {
if (styles[prop] !== !!inheritedStyles[prop]) res = `[${prop}]${res}[\/${prop}]`;
}
return res;
}
return parseNode({}, "000000", new DOMParser().parseFromString(html, "text/html").body);
}
// Demo
let html = `<span style="font-family: "Open Sans", Arial, sans-serif; font-size: 14px; text-align: justify; background-color: rgb(255, 255, 255);"><span style="text-decoration: underline;"><font color="#a9fcd4"><i>Lo<\/i><b>rem<\/b><\/font><\/span> <i style="text-decoration: underline;"><font color="#0000cc">ipsu<b>m<\/b><\/font><\/i> <b style="text-decoration: underline;"><i><font color="#cc00cc">dolor<\/font><\/i><\/b> <u><font color="#cccc00">sit<\/font><\/u> <strike><font color="#cc00cc"><b>amet<\/b><i>.<\/i><\/font><\/strike><\/span><br>`;
console.log(parse(html));