// This file is part of Desktop App Toolkit, // a set of libraries for developing nice desktop applications. // // For license and copyright information please follow this link: // https://github.com/desktop-app/legal/blob/master/LEGAL // #pragma once #include "ui/text/text.h" #include "ui/text/text_block.h" namespace Ui::Text { struct QuoteDetails; class Parser { public: Parser( not_null string, const TextWithEntities &textWithEntities, const TextParseOptions &options, const std::any &context); private: struct ReadyToken { }; class StartedEntity { public: enum class Type { Flags, Link, IndexedLink, CustomEmoji, Colorized, }; explicit StartedEntity(TextBlockFlags flags); explicit StartedEntity(uint16 index, Type type); [[nodiscard]] Type type() const; [[nodiscard]] std::optional flags() const; [[nodiscard]] std::optional linkIndex() const; [[nodiscard]] std::optional colorIndex() const; private: const int _value = 0; const Type _type; }; Parser( not_null string, TextWithEntities &&source, const TextParseOptions &options, const std::any &context, ReadyToken); void trimSourceRange(); void blockCreated(); void createBlock(int32 skipBack = 0); void createNewlineBlock(bool fromOriginalText); void ensureAtNewline(QuoteDetails quote); // Returns true if at least one entity was parsed in the current position. bool checkEntities(); void parseCurrentChar(); void parseEmojiFromCurrent(); void finalize(const TextParseOptions &options); void finishEntities(); void skipPassedEntities(); void skipBadEntities(); bool isInvalidEntity(const EntityInText &entity) const; bool isLinkEntity(const EntityInText &entity) const; bool processCustomIndex(uint16 index); void parse(const TextParseOptions &options); void computeLinkText( const QString &linkData, QString *outLinkText, EntityLinkShown *outShown); void updateModifications(int index, int delta); const not_null _t; const TextWithEntities _source; const std::any &_context; const QChar * const _start = nullptr; const QChar *_end = nullptr; // mutable, because we trim by decrementing. const QChar *_ptr = nullptr; const EntitiesInText::const_iterator _entitiesEnd; EntitiesInText::const_iterator _waitingEntity; QString _customEmojiData; const bool _multiline = false; const QFixed _stopAfterWidth; // summary width of all added words const bool _checkTilde = false; // do we need a special text block for tilde symbol std::vector _linksIndexes; std::vector _links; std::vector _monos; base::flat_map< const QChar*, std::vector> _startedEntities; uint16 _maxLinkIndex = 0; uint16 _maxShiftedLinkIndex = 0; // current state TextBlockFlags _flags; uint16 _linkIndex = 0; uint16 _colorIndex = 0; uint16 _monoIndex = 0; uint16 _quoteIndex = 0; int _quoteStartPosition = 0; EmojiPtr _emoji = nullptr; // current emoji, if current word is an emoji, or zero int32 _blockStart = 0; // offset in result, from which current parsed block is started int32 _diacritics = 0; // diacritic chars skipped without good char QFixed _sumWidth; bool _sumFinished = false; bool _newlineAwaited = false; // current char data QChar _ch; // current char (low surrogate, if current char is surrogate pair) int32 _emojiLookback = 0; // how far behind the current ptr to look for current emoji bool _allowDiacritic = false; // did we add last char to the current block }; } // namespace Ui::Text