File indexing completed on 2024-05-12 05:40:38

0001 /***************************************************************************
0002  * Copyright (C) 2014-2018 by Renaud Guezennec                              *
0003  * https://rolisteam.org/                                                *
0004  * Copyright (c) 2014-2018 Patrizio Bekerle -- http://www.bekerle.com       *
0005  *                                                                          *
0006  *  This file is part of rcse                                               *
0007  *                                                                          *
0008  * rcse is free software; you can redistribute it and/or modify             *
0009  * it under the terms of the GNU General Public License as published by     *
0010  * the Free Software Foundation; either version 2 of the License, or        *
0011  * (at your option) any later version.                                      *
0012  *                                                                          *
0013  * rcse is distributed in the hope that it will be useful,                  *
0014  * but WITHOUT ANY WARRANTY; without even the implied warranty of           *
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the             *
0016  * GNU General Public License for more details.                             *
0017  *                                                                          *
0018  * You should have received a copy of the GNU General Public License        *
0019  * along with this program; if not, write to the                            *
0020  * Free Software Foundation, Inc.,                                          *
0021  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.                 *
0022  ***************************************************************************/
0023 
0024 #ifndef MARKDOWNHIGHLIGHTER_H
0025 #define MARKDOWNHIGHLIGHTER_H
0026 
0027 #include "rwidgets_global.h"
0028 #include <QRegularExpression>
0029 #include <QSyntaxHighlighter>
0030 #include <QTextCharFormat>
0031 
0032 class QTextDocument;
0033 class QTimer;
0034 
0035 class RWIDGET_EXPORT MarkDownHighlighter : public QSyntaxHighlighter
0036 {
0037     Q_OBJECT
0038 
0039 public:
0040     enum HighlightingOption
0041     {
0042         None= 0,
0043         FullyHighlightedBlockQuote= 0x01
0044     };
0045     Q_DECLARE_FLAGS(HighlightingOptions, HighlightingOption)
0046 
0047     MarkDownHighlighter(QTextDocument* parent= nullptr,
0048                         HighlightingOptions highlightingOptions= HighlightingOption::FullyHighlightedBlockQuote);
0049 
0050     // we use some predefined numbers here to be compatible with
0051     // the peg-markdown parser
0052     enum HighlighterState
0053     {
0054         NoState= -1,
0055         Link= 0,
0056         Image= 3,
0057         CodeBlock,
0058         Italic= 7,
0059         Bold,
0060         List,
0061         Comment= 11,
0062         H1,
0063         H2,
0064         H3,
0065         H4,
0066         H5,
0067         H6,
0068         BlockQuote,
0069         HorizontalRuler= 21,
0070         Table,
0071         InlineCodeBlock,
0072         MaskedSyntax,
0073         CurrentLineBackgroundColor,
0074         BrokenLink,
0075 
0076         // internal
0077         CodeBlockEnd= 100,
0078         HeadlineEnd
0079     };
0080 
0081     void setTextFormats(QHash<HighlighterState, QTextCharFormat> formats);
0082     void setTextFormat(HighlighterState state, QTextCharFormat format);
0083     void clearDirtyBlocks();
0084     void setHighlightingOptions(HighlightingOptions options);
0085     void initHighlightingRules();
0086 
0087 signals:
0088     void highlightingFinished();
0089 
0090 protected slots:
0091     void timerTick();
0092 
0093 protected:
0094     struct HighlightingRule
0095     {
0096         QRegularExpression pattern;
0097         HighlighterState state;
0098         int capturingGroup;
0099         int maskedGroup;
0100         bool useStateAsCurrentBlockState;
0101         bool disableIfCurrentStateIsSet;
0102     };
0103 
0104     void highlightBlock(const QString& text) Q_DECL_OVERRIDE;
0105 
0106     void initTextFormats(int defaultFontSize= 12);
0107 
0108     void highlightMarkdown(QString text);
0109 
0110     void highlightHeadline(QString text);
0111 
0112     void highlightAdditionalRules(QVector<HighlightingRule>& rules, QString text);
0113 
0114     void highlightCodeBlock(QString text);
0115 
0116     void highlightCommentBlock(QString text);
0117 
0118     void addDirtyBlock(QTextBlock block);
0119 
0120     void reHighlightDirtyBlocks();
0121     void setCurrentBlockMargin(HighlighterState state);
0122 
0123 private:
0124     QVector<HighlightingRule> m_highlightingRulesPre;
0125     QVector<HighlightingRule> m_highlightingRulesAfter;
0126     QVector<QTextBlock> m_dirtyTextBlocks;
0127     QHash<HighlighterState, QTextCharFormat> m_formats;
0128     QTimer* m_timer;
0129     bool m_highlightingFinished;
0130     HighlightingOptions m_highlightingOptions;
0131 };
0132 #endif // MARKDOWNHIGHLIGHTER_H