Здравствуйте! У меня возникла необходимость адаптировать текст, который копируется из MS Word в кастомный WYSIWYG редактор. При копировании, с текстом приходят и теги со стилями. Задача состоит в том, чтобы выявлять жирный и курсивный текст, а также учитывать размер шрифта, чтобы заменять соответствующие теги на нужные. Например, приходит следующий код: <pre><code class="javascript"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"> <span style="font-size:13.999999999999998pt;font-family:Calibri,sans-serif;color:#000000;background-color:#ffffff;font-weight:400;font-style:italic;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> Тут текст </span> </p></code></pre> В этом случае нужно определить, что значение `font-style` равно `italic`, и заменить тег `span` на `strong`, удалив все инлайновые стили, чтобы получить следующий результат: <pre><code class="javascript"><p> <strong>Тут текст</strong> </p></code></pre> Вот еще один пример: <pre><code class="javascript"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"> <span style="font-size:18pt;font-family:Calibri,sans-serif;color:#000000;background-color:#ffffff;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> Тут текст </span> </p></code></pre> В этом случае нужно выявить, что `font-size` равен `18`, и заменить `span` на `h2`, в результате чего мы получим: <pre><code class="javascript"><p> <h2>Тут текст</h2> </p></code></pre> Как правильно реализовать такую логику преобразования?
Для реализации логики преобразования инлайн-стилей в соответствующие HTML-теги, вы можете использовать JavaScript или Python с библиотеками для работы с HTML. В этом примере я покажу, как вы можете реализовать эту логику на JavaScript с использованием DOMParser для обработки HTML-кода. ### Пример реализации на JavaScript Вы можете использовать следующий код, который будет обрабатывать ваш HTML-код, заменяя инлайн-стили на соответствующие теги: ```javascript function transformInlineStyles(html) { // Парсим HTML const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); // Находим все элементы <span> const spans = doc.querySelectorAll('span'); spans.forEach(span => { const style = span.getAttribute('style'); const text = span.innerHTML; // Определяем, как заменять элемент <span> if (style) { const styles = style.split(';').reduce((acc, pair) => { const [key, value] = pair.split(':').map(str => str.trim()); if (key && value) acc[key] = value; return acc; }, {}); // Проверяем на жирный текст if (styles['font-weight'] === '700') { const strong = document.createElement('strong'); strong.innerHTML = text; span.parentNode.replaceChild(strong, span); } // Проверяем на курсивный текст else if (styles['font-style'] === 'italic') { const em = document.createElement('em'); em.innerHTML = text; span.parentNode.replaceChild(em, span); } // Проверяем размер шрифта else if (styles['font-size'] && parseFloat(styles['font-size']) >= 18) { const h2 = document.createElement('h2'); h2.innerHTML = text; span.parentNode.replaceChild(h2, span); } } }); // Возвращаем обновленный HTML return doc.body.innerHTML; } const inputHTML = `<p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"> <span style="font-size:13.999999999999998pt;font-family:Calibri,sans-serif;color:#000000;background-color:#ffffff;font-weight:400;font-style:italic;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> Тут текст </span> </p>`; const outputHTML = transformInlineStyles(inputHTML); console.log(outputHTML); ``` ### Объяснение кода: 1. **Парсинг HTML:** Мы используем `DOMParser`, чтобы преобразовать строку HTML в объект, с которым можем работать. 2. **Выбор элементов `<span>`:** Мы используем `querySelectorAll` для выбора всех `<span>` элементов в документе. 3. **Обработка стилей:** С помощью `style.split(';')` мы разбиваем инлайн-стили на пары ключ-значение и сохраняем их в объекте `styles`. 4. **Замена тегов:** В зависимости от значений стилей, мы заменяем `<span>` на соответствующие теги: - Если `font-weight` равен `700`, заменяем на `<strong>`. - Если `font-style` равен `italic`, заменяем на `<em>`. - Если `font-size` больше или равен `18pt`, заменяем на `<h2>`. 5. **Возврат измененного HTML:** После того как все замены выполнены, мы возвращаем обновленный HTML-код. ### Примечания: - Данный код можно адаптировать и расширить по мере необходимости для других стилей и замен. - Если требуется обработка других стилей, просто добавьте соответствующие условия в блок `if`.
Вот тебе что-то на подобие парсера на js, который обрабатывает входной HTML-код (span, p) на целевые теги (strong, h2, и т.д.)
function processHtml(inputHtml) { // Создаешь временный DOM для парсинга HTML const parser = new DOMParser(); const doc = parser.parseFromString(inputHtml, 'text/html'); // Обрабатываешь span внутри p doc.querySelectorAll('p span[style]').forEach((span) => { const style = span.getAttribute('style'); const fontSizeMatch = style.match(/font-size:\s*([\d.]+)pt/); const fontWeightMatch = style.match(/font-weight:\s*(\d+)/); // дописать остальные регулярки (font-style и т.д.) let newElement; if (fontSizeMatch) { const fontSize = parseFloat(fontSizeMatch[1]); if (fontSize >= 18) { newElement = document.createElement('h2'); } else if (fontSize >= 16) { newElement = document.createElement('h3'); } } if (!newElement && fontWeightMatch) { const fontWeight = parseInt(fontWeightMatch[1], 10); if (fontWeight >= 700) { newElement = document.createElement('strong'); } } // Если замена нашлась, то создаешь новый элемент if (newElement) { newElement.textContent = span.textContent; span.replaceWith(newElement); } }); // Удаляешь лишние стили из p doc.querySelectorAll('p').forEach((p) => { p.removeAttribute('style'); }); return doc.body.innerHTML; // возвращаешь обработанный html } const inputHtml = ` <p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"> <span style="font-size:18pt;font-family:Calibri,sans-serif;color:#000000;background-color:#ffffff;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> Тут текст </span> </p>`; const resultHtml = processHtml(inputHtml); console.log(resultHtml);
Соответственно, если будут дополнительные условия, код можно легко расширить
https://jsfiddle.net/dfhw4eo6/