#javascript #html #css #algorithm #fonts
#javascript #HTML #css #алгоритм #шрифты
Вопрос:
В настоящее время я работаю над креативным текстовым приложением для игры Mobile Legends. Приложение может изменять цвет текста, который вы используете во время общения в игре. Есть также другие дополнения, такие как жирный шрифт, курсив, подчеркивание и зачеркивание, при этом конечным результатом является код для ввода. Приложение разработано так, чтобы быть удобным для пользователя и быстрым в использовании. Однако у меня возникли проблемы с творческими аспектами.
Сайт: https://mlcolor.netlify.app
Я создал свой собственный богатый редактор, который использует execcommand
. Мне нужно решение, которое преобразует формат HTML (который создает rich editor) в текстовый формат 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
он использует шестнадцатеричный код.
Проблема
Как мне преобразовать этот код (пример вывода):
Привет, мир!
<b><i><u><strike>Hello World!</strike></u></i></b>
в к этому:
[b][i][u][s]Hello World![/b][/i][/s]
Мое решение
Я использовал метод с использованием .replace(/<b>/g,'[b]')
. Однако, если формат становится слишком сложным, сложнее заменить теги. Код становится сложным и имеет много атрибутов.
Пример сложного формата:
remLo ipsum dolor sit
amet.
<span style="font-family: amp;quot;Open Sansamp;quot;, 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>
Отказ от ответственности: я ни в коем случае не профессиональный программист, поэтому приношу свои извинения
за любые любительские ошибки. Кодирование — это просто мое хобби в свободное время, и я
решил сделать это приложение для сообщества Mobile Legends, так как я играю
игра тоже хотела украсить мою биографию и текст чата.
Комментарии:
1. Является ли список возможных форматов «Mobile Legends» полным? Этот вопрос предназначен для предотвращения того, чтобы в ответе был комментарий «хорошо, теперь мне также нужно преобразовать цвет фона следующим образом, а также пространство строк, а также выравнивание, а также …»
2. Спасибо за ответ. Список возможных форматов уже завершен. Больше никаких дополнений. Спасибо!
3. Как экранируется обычный текст, если в нем есть специальные символы типа
[
?4. Привет! Спасибо за этот вопрос. Я действительно не рассматривал эту возможность до этого. Это будет отображаться в виде обычного текста, если они добавят специальные символы, потому что я еще не закодировал для этой части. На данный момент специальный текст в моем приложении не разрешен. Я добавлю в приложение знак, говорящий об этом. Еще раз спасибо. Это заставило меня увидеть дыру в моем приложении, которую я раньше не рассматривал.
5. Как долго настройка цвета остается действительной (поскольку нет соответствующего конечного тега)? Например
[b][FF0000]This[/b] test
. «Тест» все еще красный?
Ответ №1:
Вы должны проанализировать входные данные с помощью анализатора 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 amp;amp; node.nodeValue.trim()) {
appliedColor = inheritedColor;
return `[${appliedColor}]${node.nodeValue}`;
}
return node.nodeValue;
}
// Transfer color HTML attribute to style attribute:
if (node.nodeName === "FONT" amp;amp; 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: amp;quot;Open Sansamp;quot;, 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));
Комментарии:
1. Эй, большое вам спасибо за ответ! Это действительно сработало. Я действительно ценю вашу помощь — мне было так сложно попробовать и написать код. Как новичок, я действительно в восторге от того, как вы решили эту проблему. Было здорово учиться у вас! Еще раз, спасибо вам тысячу раз.