File indexing completed on 2024-05-12 05:04:25
0001 /** 0002 * SPDX-FileCopyrightText: 2023 Janet Black 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "textpreprocessing.h" 0008 0009 #include <QQuickTextDocument> 0010 #include <QTextBlock> 0011 #include <QTextCursor> 0012 #include <QTextDocument> 0013 0014 TextPreprocessing::TextPreprocessing(QObject *parent) 0015 : QObject(parent) 0016 { 0017 } 0018 0019 TextPreprocessing::~TextPreprocessing() 0020 { 0021 } 0022 0023 static const auto fsi = QStringLiteral("\u2068"); 0024 static const auto pdi = QStringLiteral("\u2069"); 0025 static const auto lineSeparator = QStringLiteral("\u2028"); 0026 0027 QString TextPreprocessing::preprocessHTML(const QString &html, const QColor &linkColor) 0028 { 0029 QTextDocument doc; 0030 doc.setHtml(html); 0031 0032 // transform mentions into isolates 0033 // this causes mentions to effectively be treated as opaque and non-text for 0034 // the purposes of the bidirectionality algorithim, which is how users expect 0035 // them to behave 0036 // pt 1 of 475043 fix 0037 for (auto block = doc.begin(); block != doc.end(); block = block.next()) { 0038 for (auto fragment = block.begin(); fragment != block.end(); fragment++) { 0039 auto it = fragment.fragment(); 0040 0041 if (it.charFormat().isAnchor() && it.text().startsWith(QStringLiteral("@"))) { 0042 QTextCursor curs(&doc); 0043 curs.setPosition(it.position(), QTextCursor::MoveAnchor); 0044 curs.setPosition(it.position() + it.length(), QTextCursor::KeepAnchor); 0045 curs.insertText(fsi + it.text() + pdi); 0046 } 0047 0048 // while we're iterating through fragments we might as well set the kirigami 0049 // link colour here 0050 if (it.charFormat().isAnchor()) { 0051 auto format = it.charFormat(); 0052 format.setForeground(linkColor); 0053 format.setFontUnderline(false); 0054 format.setUnderlineStyle(QTextCharFormat::NoUnderline); 0055 0056 QTextCursor curs(&doc); 0057 curs.setPosition(it.position(), QTextCursor::MoveAnchor); 0058 curs.setPosition(it.position() + it.length(), QTextCursor::KeepAnchor); 0059 curs.setCharFormat(format); 0060 } 0061 } 0062 } 0063 0064 // split apart <br> into different text blocks 0065 // so that different spans can have different layout directions 0066 // better matching bidirectionality behaviour that users are expecting 0067 // pt 2 of 475043 fix 0068 for (auto cursor = doc.find(lineSeparator); !cursor.isNull(); cursor = doc.find(lineSeparator, cursor)) { 0069 cursor.insertBlock(); 0070 } 0071 0072 return doc.toHtml(); 0073 } 0074 0075 #include "moc_textpreprocessing.cpp"