Название: Метод QTextEdit::insertHtml() съедает ведущие пробелы. Как обойти? Отправлено: xintrea от Май 22, 2016, 21:31 Решаю сейчас в своем WYSIWYG-редакторе следующую задачу:
Цитировать При вставке текста, взятого из окна браузера, текст может содержать различные теги форматирования. В программе предусмотрена кнопка для сброса форматирования текста к стандартному, заданному в настройках редактора. https://github.com/xintrea/mytetra_dev/issues/5Задача: Написать функцию (метод), очищающий форматирование выделенного текста в виджете-наследнике QTextEdit. То есть, нужно изменить только начертание символов. Ссылки должны остаться ссылками. Картинки должны остаться картинками. Таблицы должны остаться таблицами. Изменяется только начертание. При кажущейся простоте, подводных камней у этой задачи много. Сейчас я почти достиг цели - написал жуткий magick-код, который берет HTML-код выделенного фрагмета текста, обрабатывает его (убирает лишнее, подменяет теги, компенсирует многочисленные закидоны Qt-овского HTML-движка), и вставляет его обратно. Такая методика наконец-таки заработала чисто, за одним маленьким исключением: при вставке HTML-кода через метод insertHtml(), съедаются ведущие пробелы в тексте. То есть, если в тексте встретится кусок исходного кода, то indentation у него слетит. Вот пример HTML-кода до вставки и что реально вставилось: Вставляли: Код: <p style="margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;"><span style="margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;"> QMessageBox msgBox;</span></p> Получили: Код: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> Видно, что ведущие четыре пробела в каждой строчке исчезли. Код, который это делает: Код: ... Вопрос: как можно обойти эту особенность Qt, чтобы в данном случае все пробелы сохранялись? Я уже готов выбрать редко используемый UTF-8 символ (какой-нибудь иероглиф), заменить им все пробелы во вставляемом HTML, а потом заменить в документе эти символы на пробелы. Или не иероглиф, а нигде-никогда-не-встречаемую-строку. Но это же все неправильно (вдруг иероглиф кто-то использует, или так получится, что уникальная строка таки встретится). А хотелось бы правильно. А как правильно? Последний актуальный коммит: https://github.com/xintrea/mytetra_dev/commit/11bde04320971b28420f1fba217ad0ed438d43da Название: Re: Метод QTextEdit::insertHtml() съедает ведущие пробелы. Как обойти? Отправлено: gil9red от Май 22, 2016, 21:43 html к пробелам не очень хорошо относится
заменяйте пробелы строкой " " Название: Re: Метод QTextEdit::insertHtml() съедает ведущие пробелы. Как обойти? Отправлено: xintrea от Май 22, 2016, 22:40 html к пробелам не очень хорошо относится заменяйте пробелы строкой " " Вот сам подумай. Ты предлагаешь заменить пробелы на неразрывные пробелы. А потом их нужно поменять на обычные пробелы. Вопрос. Как ты отличишь неразрывные пробелы, которые внесены были искусственно от неразрывных пробелов, которые изначально были в тексте? И второе. Чтобы твой метод проверить, нужно решить другую задачу: как в HTML поменять пробел " " на на неразрывный пробел «амперсандnbsp;» так, чтобы захватились только пробелы в тексте. А пробелы в тегах и в атрибутах не затронулись. Что-то я не могу составить такую заковыристую регулярку. В Qt в QRegEx еще есть проблема обработки многострочных строк - если регулярка попадет на перенос строки, она не отработает. Название: Re: Метод QTextEdit::insertHtml() съедает ведущие пробелы. Как обойти? Отправлено: xintrea от Май 23, 2016, 00:20 html к пробелам не очень хорошо относится заменяйте пробелы строкой " " Решил сделать по-честному: распарсить HTML через DOM XML, и заменить пробелы на " " только в текстовых узлах. Загружаю HTML-код в QDomDocument. Прочесываю его рекурсивно такой функцией: Код: void TypefaceFormatter::recurseReplaceSpaces(const QDomNode &node) В ходе ее работы вижу: Код: 00:10:33 [DBG] Replace spaces: " QMessageBox msgBox;" Казалось бы, вопрос решен? Нет! Когда генерируем HTML из этого DOM-дерева через метод doc.toString(), символ «&» заменяется на «&», и мы получаем каку: Код: <p style="margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;"> В какой момент происходит эта подмена, понять не могу. То ли сразу при установке значения текстового узла, то ли при генерации doc.toString(). Факт в том, что из DOM не могу получить HTML с « ». А это ключевое ключевое действие, которое надо сделать. |