Use double underscores for italic chat markup
This commit is contained in:
1 parent
b17c6fff96
commit
66b8da36b8
2 files changed
+8
-7
No files matched your search
@@ -24,7 +24,7 @@ bool MessageText::isCode(int position) const {
|
||||
|
||||
namespace {
|
||||
struct Marker {
|
||||
int position, length, kind; // Позиция в строке после escapes; kind: 0=**, 1=*, 2=~~.
|
||||
int position, length, kind; // Позиция в строке после escapes; kind: 0=**, 1=__, 2=~~.
|
||||
bool open, close; // Открытие/закрытие допустимо только около непустого текста.
|
||||
int nextClose = -1; // Следующий закрывающий маркер того же вида; поиск за O(n).
|
||||
};
|
||||
@@ -39,19 +39,19 @@ void appendInline(MessageText& result, const QString& source) {
|
||||
while (linkIndex < links.size() && links[linkIndex].start + links[linkIndex].length <= i) ++linkIndex;
|
||||
const bool inLink = linkIndex < links.size() && links[linkIndex].start <= i;
|
||||
const QChar ch = source[i];
|
||||
if (!inLink && ch == '\\' && i + 1 < source.size() && QStringLiteral("*~`\\").contains(source[i + 1])) {
|
||||
if (!inLink && ch == '\\' && i + 1 < source.size() && QStringLiteral("*_~`\\").contains(source[i + 1])) {
|
||||
line += source[i + 1]; i += 2; result.changed = true; continue;
|
||||
}
|
||||
int count = 1;
|
||||
if (ch == '*' || ch == '~') {
|
||||
if (ch == '*' || ch == '_' || ch == '~') {
|
||||
while (i + count < source.size() && source[i + count] == ch) ++count;
|
||||
if ((ch == '*' && count <= 2) || (ch == '~' && count == 2)) {
|
||||
if (count == 2) {
|
||||
const bool open = !inLink && i + count < source.size() && !source[i + count].isSpace()
|
||||
&& (i == 0 || !source[i - 1].isLetterOrNumber());
|
||||
const bool close = i > 0 && !source[i - 1].isSpace()
|
||||
&& (!inLink || i + count == links[linkIndex].start + links[linkIndex].length)
|
||||
&& (i + count == source.size() || !source[i + count].isLetterOrNumber());
|
||||
markers.append({int(line.size()), count, ch == '~' ? 2 : count == 2 ? 0 : 1, open, close});
|
||||
markers.append({int(line.size()), count, ch == '*' ? 0 : ch == '_' ? 1 : 2, open, close});
|
||||
}
|
||||
}
|
||||
line += source.mid(i, count); i += count;
|
||||
@@ -152,7 +152,8 @@ QSharedPointer<const MessageText> formattedMessageText(const QModelIndex& index)
|
||||
const QString type = index.data(MsgContentTypeRole).toString();
|
||||
if ((!type.isEmpty() && type != "text/plain") || !index.data(MsgInviteLinkRole).toString().isEmpty()) return {};
|
||||
const QString source = index.data(MsgTextRole).toString();
|
||||
if (!source.contains('*') && !source.contains("~~") && !source.contains('`') && !source.contains('\\')) return {};
|
||||
if (!source.contains("**") && !source.contains("__") && !source.contains("~~") && !source.contains('`') && !source.contains('\\'))
|
||||
return {};
|
||||
// Ограничение учитывает текст ключа, видимый текст и диапазоны; shared pointer жив до конца paint/hit-test.
|
||||
static QCache<QString, QSharedPointer<const MessageText>> cache(8 * 1024 * 1024);
|
||||
if (const auto* cached = cache.object(source)) return *cached;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Разметка текста сообщений: **жирный**, *курсив*, ~~зачёркнутый~~ и отдельные строки ```[язык]/```.
|
||||
/* Разметка текста сообщений: **жирный**, __курсив__, ~~зачёркнутый~~ и отдельные строки ```[язык]/```.
|
||||
* Исходник модели не меняется. GUI-поток получает кешированный видимый текст, ссылки и цвета синтаксиса.
|
||||
* Один QTextLayout используется для размеров, рисования и выделения; clipboard берёт MessageText::text. */
|
||||
#pragma once
|
||||
|
||||
Reference in new issue
Block a user