Removed text commands.
This commit is contained in:
parent
09b56b019b
commit
7e279bd83a
4 changed files with 29 additions and 484 deletions
305
ui/text/text.cpp
305
ui/text/text.cpp
|
|
@ -156,112 +156,6 @@ bool IsBad(QChar ch) {
|
|||
} // namespace Text
|
||||
} // namespace Ui
|
||||
|
||||
QString textcmdSkipBlock(ushort w, ushort h) {
|
||||
static QString cmd(5, TextCommand);
|
||||
cmd[1] = QChar(TextCommandSkipBlock);
|
||||
cmd[2] = QChar(w);
|
||||
cmd[3] = QChar(h);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
QString textcmdStartLink(ushort lnkIndex) {
|
||||
static QString cmd(4, TextCommand);
|
||||
cmd[1] = QChar(TextCommandLinkIndex);
|
||||
cmd[2] = QChar(lnkIndex);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
QString textcmdStartLink(const QString &url) {
|
||||
if (url.size() >= 4096) return QString();
|
||||
|
||||
QString result;
|
||||
result.reserve(url.size() + 4);
|
||||
return result.append(TextCommand).append(QChar(TextCommandLinkText)).append(QChar(int(url.size()))).append(url).append(TextCommand);
|
||||
}
|
||||
|
||||
QString textcmdStopLink() {
|
||||
return textcmdStartLink(0);
|
||||
}
|
||||
|
||||
QString textcmdLink(ushort lnkIndex, const QString &text) {
|
||||
QString result;
|
||||
result.reserve(4 + text.size() + 4);
|
||||
return result.append(textcmdStartLink(lnkIndex)).append(text).append(textcmdStopLink());
|
||||
}
|
||||
|
||||
QString textcmdLink(const QString &url, const QString &text) {
|
||||
QString result;
|
||||
result.reserve(4 + url.size() + text.size() + 4);
|
||||
return result.append(textcmdStartLink(url)).append(text).append(textcmdStopLink());
|
||||
}
|
||||
|
||||
QString textcmdStartSemibold() {
|
||||
QString result;
|
||||
result.reserve(3);
|
||||
return result.append(TextCommand).append(QChar(TextCommandSemibold)).append(TextCommand);
|
||||
}
|
||||
|
||||
QString textcmdStopSemibold() {
|
||||
QString result;
|
||||
result.reserve(3);
|
||||
return result.append(TextCommand).append(QChar(TextCommandNoSemibold)).append(TextCommand);
|
||||
}
|
||||
|
||||
QString textcmdStartSpoiler() {
|
||||
QString result;
|
||||
result.reserve(3);
|
||||
return result.append(TextCommand).append(QChar(TextCommandSpoiler)).append(TextCommand);
|
||||
}
|
||||
|
||||
QString textcmdStopSpoiler() {
|
||||
QString result;
|
||||
result.reserve(3);
|
||||
return result.append(TextCommand).append(QChar(TextCommandNoSpoiler)).append(TextCommand);
|
||||
}
|
||||
|
||||
const QChar *textSkipCommand(const QChar *from, const QChar *end, bool canLink) {
|
||||
const QChar *result = from + 1;
|
||||
if (*from != TextCommand || result >= end) return from;
|
||||
|
||||
ushort cmd = result->unicode();
|
||||
++result;
|
||||
if (result >= end) return from;
|
||||
|
||||
switch (cmd) {
|
||||
case TextCommandBold:
|
||||
case TextCommandNoBold:
|
||||
case TextCommandSemibold:
|
||||
case TextCommandNoSemibold:
|
||||
case TextCommandItalic:
|
||||
case TextCommandNoItalic:
|
||||
case TextCommandUnderline:
|
||||
case TextCommandNoUnderline:
|
||||
case TextCommandSpoiler:
|
||||
case TextCommandNoSpoiler:
|
||||
break;
|
||||
|
||||
case TextCommandLinkIndex:
|
||||
if (result->unicode() > 0x7FFF) return from;
|
||||
++result;
|
||||
break;
|
||||
|
||||
case TextCommandLinkText: {
|
||||
ushort len = result->unicode();
|
||||
if (len >= 4096 || !canLink) return from;
|
||||
result += len + 1;
|
||||
} break;
|
||||
|
||||
case TextCommandSkipBlock:
|
||||
result += 2;
|
||||
break;
|
||||
|
||||
case TextCommandLangTag:
|
||||
result += 1;
|
||||
break;
|
||||
}
|
||||
return (result < end && *result == TextCommand) ? (result + 1) : from;
|
||||
}
|
||||
|
||||
const TextParseOptions _defaultOptions = {
|
||||
TextParseLinks | TextParseMultiline, // flags
|
||||
0, // maxw
|
||||
|
|
@ -328,15 +222,11 @@ private:
|
|||
void createBlock(int32 skipBack = 0);
|
||||
void createSkipBlock(int32 w, int32 h);
|
||||
void createNewlineBlock();
|
||||
bool checkCommand();
|
||||
|
||||
// Returns true if at least one entity was parsed in the current position.
|
||||
bool checkEntities();
|
||||
bool readSkipBlockCommand();
|
||||
bool readCommand();
|
||||
void parseCurrentChar();
|
||||
void parseEmojiFromCurrent();
|
||||
void checkForElidedSkipBlock();
|
||||
void finalize(const TextParseOptions &options);
|
||||
|
||||
void finishEntities();
|
||||
|
|
@ -528,17 +418,6 @@ void Parser::createNewlineBlock() {
|
|||
createBlock();
|
||||
}
|
||||
|
||||
bool Parser::checkCommand() {
|
||||
bool result = false;
|
||||
for (QChar c = ((_ptr < _end) ? *_ptr : 0); c == TextCommand; c = ((_ptr < _end) ? *_ptr : 0)) {
|
||||
if (!readCommand()) {
|
||||
break;
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Parser::finishEntities() {
|
||||
while (!_startedEntities.empty()
|
||||
&& (_ptr >= _startedEntities.begin()->first || _ptr >= _end)) {
|
||||
|
|
@ -691,149 +570,6 @@ void Parser::skipBadEntities() {
|
|||
}
|
||||
}
|
||||
|
||||
bool Parser::readSkipBlockCommand() {
|
||||
const QChar *afterCmd = textSkipCommand(_ptr, _end, _links.size() < 0x7FFF);
|
||||
if (afterCmd == _ptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ushort cmd = (++_ptr)->unicode();
|
||||
++_ptr;
|
||||
|
||||
switch (cmd) {
|
||||
case TextCommandSkipBlock:
|
||||
createSkipBlock(_ptr->unicode(), (_ptr + 1)->unicode());
|
||||
break;
|
||||
}
|
||||
|
||||
_ptr = afterCmd;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::readCommand() {
|
||||
const QChar *afterCmd = textSkipCommand(_ptr, _end, _links.size() < 0x7FFF);
|
||||
if (afterCmd == _ptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ushort cmd = (++_ptr)->unicode();
|
||||
++_ptr;
|
||||
|
||||
switch (cmd) {
|
||||
case TextCommandBold:
|
||||
if (!(_flags & TextBlockFBold)) {
|
||||
createBlock();
|
||||
_flags |= TextBlockFBold;
|
||||
}
|
||||
break;
|
||||
|
||||
case TextCommandNoBold:
|
||||
if (_flags & TextBlockFBold) {
|
||||
createBlock();
|
||||
_flags &= ~TextBlockFBold;
|
||||
}
|
||||
break;
|
||||
|
||||
case TextCommandSemibold:
|
||||
if (!(_flags & TextBlockFSemibold)) {
|
||||
createBlock();
|
||||
_flags |= TextBlockFSemibold;
|
||||
}
|
||||
break;
|
||||
|
||||
case TextCommandNoSemibold:
|
||||
if (_flags & TextBlockFSemibold) {
|
||||
createBlock();
|
||||
_flags &= ~TextBlockFSemibold;
|
||||
}
|
||||
break;
|
||||
|
||||
case TextCommandItalic:
|
||||
if (!(_flags & TextBlockFItalic)) {
|
||||
createBlock();
|
||||
_flags |= TextBlockFItalic;
|
||||
}
|
||||
break;
|
||||
|
||||
case TextCommandNoItalic:
|
||||
if (_flags & TextBlockFItalic) {
|
||||
createBlock();
|
||||
_flags &= ~TextBlockFItalic;
|
||||
}
|
||||
break;
|
||||
|
||||
case TextCommandUnderline:
|
||||
if (!(_flags & TextBlockFUnderline)) {
|
||||
createBlock();
|
||||
_flags |= TextBlockFUnderline;
|
||||
}
|
||||
break;
|
||||
|
||||
case TextCommandNoUnderline:
|
||||
if (_flags & TextBlockFUnderline) {
|
||||
createBlock();
|
||||
_flags &= ~TextBlockFUnderline;
|
||||
}
|
||||
break;
|
||||
|
||||
case TextCommandStrikeOut:
|
||||
if (!(_flags & TextBlockFStrikeOut)) {
|
||||
createBlock();
|
||||
_flags |= TextBlockFStrikeOut;
|
||||
}
|
||||
break;
|
||||
|
||||
case TextCommandNoStrikeOut:
|
||||
if (_flags & TextBlockFStrikeOut) {
|
||||
createBlock();
|
||||
_flags &= ~TextBlockFStrikeOut;
|
||||
}
|
||||
break;
|
||||
|
||||
case TextCommandLinkIndex:
|
||||
if (_ptr->unicode() != _lnkIndex) {
|
||||
createBlock();
|
||||
_lnkIndex = _ptr->unicode();
|
||||
}
|
||||
break;
|
||||
|
||||
case TextCommandLinkText: {
|
||||
createBlock();
|
||||
int32 len = _ptr->unicode();
|
||||
_links.push_back(EntityLinkData{
|
||||
.data = QString(++_ptr, len),
|
||||
.type = EntityType::CustomUrl
|
||||
});
|
||||
_lnkIndex = kStringLinkIndexShift + _links.size();
|
||||
} break;
|
||||
|
||||
case TextCommandSpoiler: {
|
||||
if (!_spoilerIndex) {
|
||||
createBlock();
|
||||
_spoilers.push_back(EntityLinkData{
|
||||
.data = QString::number(_spoilers.size() + 1),
|
||||
.type = EntityType::Spoiler,
|
||||
});
|
||||
_spoilerIndex = _spoilers.size();
|
||||
}
|
||||
} break;
|
||||
|
||||
case TextCommandNoSpoiler:
|
||||
if (_spoilerIndex == _spoilers.size()) {
|
||||
createBlock();
|
||||
_spoilerIndex = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case TextCommandSkipBlock:
|
||||
createSkipBlock(_ptr->unicode(), (_ptr + 1)->unicode());
|
||||
break;
|
||||
}
|
||||
|
||||
_ptr = afterCmd;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Parser::parseCurrentChar() {
|
||||
_ch = ((_ptr < _end) ? *_ptr : 0);
|
||||
_emojiLookback = 0;
|
||||
|
|
@ -964,7 +700,7 @@ void Parser::parse(const TextParseOptions &options) {
|
|||
_t->_text.reserve(_end - _ptr);
|
||||
|
||||
for (; _ptr <= _end; ++_ptr) {
|
||||
while (checkEntities() || (_rich && checkCommand())) {
|
||||
while (checkEntities()) {
|
||||
}
|
||||
parseCurrentChar();
|
||||
parseEmojiFromCurrent();
|
||||
|
|
@ -974,7 +710,6 @@ void Parser::parse(const TextParseOptions &options) {
|
|||
}
|
||||
}
|
||||
createBlock();
|
||||
checkForElidedSkipBlock();
|
||||
finalize(options);
|
||||
}
|
||||
|
||||
|
|
@ -983,25 +718,25 @@ void Parser::trimSourceRange() {
|
|||
_source.entities,
|
||||
_end - _start);
|
||||
|
||||
while (_ptr != _end && IsTrimmed(*_ptr, _rich) && _ptr != _start + firstMonospaceOffset) {
|
||||
while (_ptr != _end && IsTrimmed(*_ptr) && _ptr != _start + firstMonospaceOffset) {
|
||||
++_ptr;
|
||||
}
|
||||
while (_ptr != _end && IsTrimmed(*(_end - 1), _rich)) {
|
||||
while (_ptr != _end && IsTrimmed(*(_end - 1))) {
|
||||
--_end;
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::checkForElidedSkipBlock() {
|
||||
if (!_sumFinished || !_rich) {
|
||||
return;
|
||||
}
|
||||
// We could've skipped the final skip block command.
|
||||
for (; _ptr < _end; ++_ptr) {
|
||||
if (*_ptr == TextCommand && readSkipBlockCommand()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// void Parser::checkForElidedSkipBlock() {
|
||||
// if (!_sumFinished || !_rich) {
|
||||
// return;
|
||||
// }
|
||||
// // We could've skipped the final skip block command.
|
||||
// for (; _ptr < _end; ++_ptr) {
|
||||
// if (*_ptr == TextCommand && readSkipBlockCommand()) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
void Parser::finalize(const TextParseOptions &options) {
|
||||
_t->_links.resize(_maxLnkIndex);
|
||||
|
|
@ -3795,8 +3530,7 @@ bool IsAlmostLinkEnd(QChar ch) {
|
|||
}
|
||||
|
||||
bool IsLinkEnd(QChar ch) {
|
||||
return (ch == TextCommand)
|
||||
|| IsBad(ch)
|
||||
return IsBad(ch)
|
||||
|| IsSpace(ch)
|
||||
|| IsNewline(ch)
|
||||
|| ch.isLowSurrogate()
|
||||
|
|
@ -3808,9 +3542,9 @@ bool IsNewline(QChar ch) {
|
|||
|| (ch == 156);
|
||||
}
|
||||
|
||||
bool IsSpace(QChar ch, bool rich) {
|
||||
bool IsSpace(QChar ch) {
|
||||
return ch.isSpace()
|
||||
|| (ch < 32 && !(rich && ch == TextCommand))
|
||||
|| (ch < 32)
|
||||
|| (ch == QChar::ParagraphSeparator)
|
||||
|| (ch == QChar::LineSeparator)
|
||||
|| (ch == QChar::ObjectReplacementCharacter)
|
||||
|
|
@ -3840,9 +3574,8 @@ bool IsReplacedBySpace(QChar ch) {
|
|||
|| (ch >= 8232 && ch <= 8237);
|
||||
}
|
||||
|
||||
bool IsTrimmed(QChar ch, bool rich) {
|
||||
return (!rich || ch != TextCommand)
|
||||
&& (IsSpace(ch) || IsBad(ch));
|
||||
bool IsTrimmed(QChar ch) {
|
||||
return (IsSpace(ch) || IsBad(ch));
|
||||
}
|
||||
|
||||
} // namespace Text
|
||||
|
|
|
|||
|
|
@ -22,25 +22,6 @@ static const auto kQEllipsis = QStringLiteral("...");
|
|||
} // namespace Ui
|
||||
|
||||
static const QChar TextCommand(0x0010);
|
||||
enum TextCommands {
|
||||
TextCommandBold = 0x01,
|
||||
TextCommandNoBold = 0x02,
|
||||
TextCommandItalic = 0x03,
|
||||
TextCommandNoItalic = 0x04,
|
||||
TextCommandUnderline = 0x05,
|
||||
TextCommandNoUnderline = 0x06,
|
||||
TextCommandStrikeOut = 0x07,
|
||||
TextCommandNoStrikeOut = 0x08,
|
||||
TextCommandSemibold = 0x09,
|
||||
TextCommandNoSemibold = 0x0A,
|
||||
TextCommandLinkIndex = 0x0B, // 0 - NoLink
|
||||
TextCommandLinkText = 0x0C,
|
||||
TextCommandSkipBlock = 0x0D,
|
||||
TextCommandSpoiler = 0x0E,
|
||||
TextCommandNoSpoiler = 0x0F,
|
||||
|
||||
TextCommandLangTag = 0x20,
|
||||
};
|
||||
|
||||
struct TextParseOptions {
|
||||
int32 flags;
|
||||
|
|
@ -253,10 +234,10 @@ private:
|
|||
[[nodiscard]] bool IsAlmostLinkEnd(QChar ch);
|
||||
[[nodiscard]] bool IsLinkEnd(QChar ch);
|
||||
[[nodiscard]] bool IsNewline(QChar ch);
|
||||
[[nodiscard]] bool IsSpace(QChar ch, bool rich = false);
|
||||
[[nodiscard]] bool IsSpace(QChar ch);
|
||||
[[nodiscard]] bool IsDiac(QChar ch);
|
||||
[[nodiscard]] bool IsReplacedBySpace(QChar ch);
|
||||
[[nodiscard]] bool IsTrimmed(QChar ch, bool rich = false);
|
||||
[[nodiscard]] bool IsTrimmed(QChar ch);
|
||||
|
||||
} // namespace Text
|
||||
} // namespace Ui
|
||||
|
|
@ -276,18 +257,3 @@ inline TextSelection shiftSelection(TextSelection selection, const Ui::Text::Str
|
|||
inline TextSelection unshiftSelection(TextSelection selection, const Ui::Text::String &byText) {
|
||||
return unshiftSelection(selection, byText.length());
|
||||
}
|
||||
|
||||
// textcmd
|
||||
QString textcmdSkipBlock(ushort w, ushort h);
|
||||
QString textcmdStartLink(ushort lnkIndex);
|
||||
QString textcmdStartLink(const QString &url);
|
||||
QString textcmdStopLink();
|
||||
QString textcmdLink(ushort lnkIndex, const QString &text);
|
||||
QString textcmdLink(const QString &url, const QString &text);
|
||||
QString textcmdStartSemibold();
|
||||
QString textcmdStopSemibold();
|
||||
|
||||
QString textcmdStartSpoiler();
|
||||
QString textcmdStopSpoiler();
|
||||
|
||||
const QChar *textSkipCommand(const QChar *from, const QChar *end, bool canLink = true);
|
||||
|
|
|
|||
|
|
@ -1293,35 +1293,17 @@ bool IsValidTopDomain(const QString &protocol) {
|
|||
return list.contains(base::crc32(protocol.constData(), protocol.size() * sizeof(QChar)));
|
||||
}
|
||||
|
||||
QString Clean(const QString &text, bool keepSpoilers) {
|
||||
auto result = text;
|
||||
for (auto s = text.unicode(), ch = s, e = text.unicode() + text.size(); ch != e; ++ch) {
|
||||
if (keepSpoilers && (*ch == TextCommand)) {
|
||||
if ((*(ch + 1) == TextCommandSpoiler)
|
||||
|| (*(ch - 1) == TextCommandSpoiler)
|
||||
|| (*(ch + 1) == TextCommandNoSpoiler)
|
||||
|| (*(ch - 1) == TextCommandNoSpoiler)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (*ch == TextCommand) {
|
||||
result[int(ch - s)] = QChar::Space;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QString EscapeForRichParsing(const QString &text) {
|
||||
QString result;
|
||||
result.reserve(text.size());
|
||||
auto s = text.constData(), ch = s;
|
||||
for (const QChar *e = s + text.size(); ch != e; ++ch) {
|
||||
if (*ch == TextCommand) {
|
||||
if (ch > s) result.append(s, ch - s);
|
||||
result.append(QChar::Space);
|
||||
s = ch + 1;
|
||||
continue;
|
||||
}
|
||||
// if (*ch == TextCommand) {
|
||||
// if (ch > s) result.append(s, ch - s);
|
||||
// result.append(QChar::Space);
|
||||
// s = ch + 1;
|
||||
// continue;
|
||||
// }
|
||||
if (ch->unicode() == '\\' || ch->unicode() == '[') {
|
||||
if (ch > s) result.append(s, ch - s);
|
||||
result.append('\\');
|
||||
|
|
@ -1349,7 +1331,7 @@ QString SingleLine(const QString &text) {
|
|||
}
|
||||
|
||||
for (auto ch = s; ch != e; ++ch) {
|
||||
if (IsNewline(*ch) || *ch == TextCommand) {
|
||||
if (IsNewline(*ch)/* || *ch == TextCommand*/) {
|
||||
result[int(ch - s)] = QChar::Space;
|
||||
}
|
||||
}
|
||||
|
|
@ -1545,47 +1527,6 @@ bool CutPart(TextWithEntities &sending, TextWithEntities &left, int32 limit) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool textcmdStartsLink(const QChar *start, int32 len, int32 commandOffset) {
|
||||
if (commandOffset + 2 < len) {
|
||||
if (*(start + commandOffset + 1) == TextCommandLinkIndex) {
|
||||
return (*(start + commandOffset + 2) != 0);
|
||||
}
|
||||
return (*(start + commandOffset + 1) != TextCommandLinkText);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool checkTagStartInCommand(const QChar *start, int32 len, int32 tagStart, int32 &commandOffset, bool &commandIsLink, bool &inLink) {
|
||||
bool inCommand = false;
|
||||
const QChar *commandEnd = start + commandOffset;
|
||||
while (commandOffset < len && tagStart > commandOffset) { // skip commands, evaluating are we in link or not
|
||||
commandEnd = textSkipCommand(start + commandOffset, start + len);
|
||||
if (commandEnd > start + commandOffset) {
|
||||
if (tagStart < (commandEnd - start)) {
|
||||
inCommand = true;
|
||||
break;
|
||||
}
|
||||
for (commandOffset = commandEnd - start; commandOffset < len; ++commandOffset) {
|
||||
if (*(start + commandOffset) == TextCommand) {
|
||||
inLink = commandIsLink;
|
||||
commandIsLink = textcmdStartsLink(start, len, commandOffset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (commandOffset >= len) {
|
||||
inLink = commandIsLink;
|
||||
commandIsLink = false;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (inCommand) {
|
||||
commandOffset = commandEnd - start;
|
||||
}
|
||||
return inCommand;
|
||||
}
|
||||
|
||||
TextWithEntities ParseEntities(const QString &text, int32 flags) {
|
||||
const auto rich = ((flags & TextParseRichText) != 0);
|
||||
auto result = TextWithEntities{ text, EntitiesInText() };
|
||||
|
|
@ -1605,20 +1546,10 @@ void ParseEntities(TextWithEntities &result, int32 flags, bool rich) {
|
|||
int existingEntityIndex = 0, existingEntitiesCount = result.entities.size();
|
||||
int existingEntityEnd = 0;
|
||||
|
||||
int32 len = result.text.size(), commandOffset = rich ? 0 : len;
|
||||
bool inLink = false, commandIsLink = false;
|
||||
int32 len = result.text.size();
|
||||
const auto start = result.text.constData();
|
||||
const auto end = start + result.text.size();
|
||||
for (int32 offset = 0, matchOffset = offset, mentionSkip = 0; offset < len;) {
|
||||
if (commandOffset <= offset) {
|
||||
for (commandOffset = offset; commandOffset < len; ++commandOffset) {
|
||||
if (*(start + commandOffset) == TextCommand) {
|
||||
inLink = commandIsLink;
|
||||
commandIsLink = textcmdStartsLink(start, len, commandOffset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
auto mDomain = qthelp::RegExpDomain().match(result.text, matchOffset);
|
||||
auto mExplicitDomain = qthelp::RegExpDomainExplicit().match(result.text, matchOffset);
|
||||
auto mHashtag = withHashtags ? RegExpHashtag().match(result.text, matchOffset) : QRegularExpressionMatch();
|
||||
|
|
@ -1706,17 +1637,6 @@ void ParseEntities(TextWithEntities &result, int32 flags, bool rich) {
|
|||
offset = matchOffset = mentionEnd;
|
||||
continue;
|
||||
}
|
||||
const auto inCommand = checkTagStartInCommand(
|
||||
start,
|
||||
len,
|
||||
mentionStart,
|
||||
commandOffset,
|
||||
commandIsLink,
|
||||
inLink);
|
||||
if (inCommand || inLink) {
|
||||
offset = matchOffset = commandOffset;
|
||||
continue;
|
||||
}
|
||||
|
||||
lnkType = EntityType::Mention;
|
||||
lnkStart = mentionStart;
|
||||
|
|
@ -1727,50 +1647,15 @@ void ParseEntities(TextWithEntities &result, int32 flags, bool rich) {
|
|||
offset = matchOffset = hashtagEnd;
|
||||
continue;
|
||||
}
|
||||
const auto inCommand = checkTagStartInCommand(
|
||||
start,
|
||||
len,
|
||||
hashtagStart,
|
||||
commandOffset,
|
||||
commandIsLink,
|
||||
inLink);
|
||||
if (inCommand || inLink) {
|
||||
offset = matchOffset = commandOffset;
|
||||
continue;
|
||||
}
|
||||
|
||||
lnkType = EntityType::Hashtag;
|
||||
lnkStart = hashtagStart;
|
||||
lnkLength = hashtagEnd - hashtagStart;
|
||||
} else if (botCommandStart < domainStart) {
|
||||
const auto inCommand = checkTagStartInCommand(
|
||||
start,
|
||||
len,
|
||||
botCommandStart,
|
||||
commandOffset,
|
||||
commandIsLink,
|
||||
inLink);
|
||||
if (inCommand || inLink) {
|
||||
offset = matchOffset = commandOffset;
|
||||
continue;
|
||||
}
|
||||
|
||||
lnkType = EntityType::BotCommand;
|
||||
lnkStart = botCommandStart;
|
||||
lnkLength = botCommandEnd - botCommandStart;
|
||||
} else {
|
||||
const auto inCommand = checkTagStartInCommand(
|
||||
start,
|
||||
len,
|
||||
domainStart,
|
||||
commandOffset,
|
||||
commandIsLink,
|
||||
inLink);
|
||||
if (inCommand || inLink) {
|
||||
offset = matchOffset = commandOffset;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto protocol = mDomain.captured(1).toLower();
|
||||
auto topDomain = mDomain.captured(3).toLower();
|
||||
auto isProtocolValid = protocol.isEmpty() || IsValidProtocol(protocol);
|
||||
|
|
@ -2332,36 +2217,6 @@ void SetClipboardText(
|
|||
}
|
||||
}
|
||||
|
||||
QString TextWithSpoilerCommands(const TextWithEntities &textWithEntities) {
|
||||
auto text = textWithEntities.text;
|
||||
auto offset = 0;
|
||||
const auto start = textcmdStartSpoiler();
|
||||
const auto stop = textcmdStopSpoiler();
|
||||
for (const auto &e : textWithEntities.entities) {
|
||||
if (e.type() == EntityType::Spoiler) {
|
||||
text.insert(e.offset() + offset, start);
|
||||
offset += start.size();
|
||||
text.insert(e.offset() + e.length() + offset, stop);
|
||||
offset += stop.size();
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
QString CutTextWithCommands(
|
||||
QString text,
|
||||
int length,
|
||||
const QString &start,
|
||||
const QString &stop) {
|
||||
text = text.mid(0, length);
|
||||
const auto lastStart = text.lastIndexOf(start);
|
||||
const auto lastStop = text.lastIndexOf(stop);
|
||||
const auto additional = ((lastStart == -1) || (lastStart < lastStop))
|
||||
? QString()
|
||||
: stop;
|
||||
return text + additional + Ui::kQEllipsis;
|
||||
}
|
||||
|
||||
} // namespace TextUtilities
|
||||
|
||||
EntityInText::EntityInText(
|
||||
|
|
|
|||
|
|
@ -297,7 +297,6 @@ QString MarkdownSpoilerGoodBefore();
|
|||
QString MarkdownSpoilerBadAfter();
|
||||
|
||||
// Text preprocess.
|
||||
QString Clean(const QString &text, bool keepSpoilers = false);
|
||||
QString EscapeForRichParsing(const QString &text);
|
||||
QString SingleLine(const QString &text);
|
||||
TextWithEntities SingleLine(const TextWithEntities &text);
|
||||
|
|
@ -383,12 +382,4 @@ void SetClipboardText(
|
|||
const TextForMimeData &text,
|
||||
QClipboard::Mode mode = QClipboard::Clipboard);
|
||||
|
||||
[[nodiscard]] QString TextWithSpoilerCommands(
|
||||
const TextWithEntities &textWithEntities);
|
||||
[[nodiscard]] QString CutTextWithCommands(
|
||||
QString text,
|
||||
int length,
|
||||
const QString &start,
|
||||
const QString &stop);
|
||||
|
||||
} // namespace TextUtilities
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue