-
Notifications
You must be signed in to change notification settings - Fork 351
/
Copy pathsyntaxcheck.h
156 lines (134 loc) · 5.97 KB
/
syntaxcheck.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#ifndef Header_SyntaxCheck
#define Header_SyntaxCheck
#include "mostQtHeaders.h"
#include "smallUsefulFunctions.h"
#include "latexparser/latexparser.h"
#include "qdocumentline_p.h"
#include <QThread>
#include <QSemaphore>
#include <QMutex>
#include <QQueue>
class SpellerUtility;
/*!
* \brief store information on open environments
*/
class Environment
{
public:
Environment(): id(-1), excessCol(0), dlh(nullptr),endingColumn(-1) , ticket(0), level(0) {} ///< constructor
QString name; ///< name of environment, partially an alias is used, e.g. math instead of '$'
QString origName; ///< original name of environment if alias is used, otherwise empty
int id; ///< mostly unused, contains the number of columns for tabular-environments
int excessCol; ///< number of unused tabular-columns if columns are strechted over several text lines
QDocumentLineHandle *dlh; ///< linehandle of starting line
int startingColumn;
int endingColumn;
int ticket;
int level; ///< command level (see tokens) in order to handle nested commands like \shortstack
bool operator ==(const Environment &env) const
{
return (name == env.name) && (id == env.id) && (excessCol == env.excessCol) && (origName == env.origName) && (level == env.level);
}
bool operator !=(const Environment &env) const
{
return (name != env.name) || (id != env.id) || (excessCol != env.excessCol) || (origName != env.origName) || (level != env.level);
}
};
typedef QStack<Environment> StackEnvironment;
Q_DECLARE_METATYPE(StackEnvironment)
class SyntaxCheck : public SafeThread
{
Q_OBJECT
public:
/*!
* \brief type of error
*/
enum ErrorType {
ERR_none, ///< no error
ERR_unrecognizedEnvironment, ///< environment unknown
ERR_unrecognizedCommand, ///< command unknown
ERR_unrecognizedMathCommand, ///< unknown command for math environment
ERR_unrecognizedTabularCommand, ///< unknown command for tabular environment
ERR_TabularCommandOutsideTab, ///< tabular command outside tabular (e.g. \hline)
ERR_MathCommandOutsideMath, ///< math command outside of math env
ERR_TabbingCommandOutside, ///< tabbing command outside of tabbing env
ERR_tooManyCols, ///< tabular has more columns in line than in definition
ERR_tooLittleCols, ///< tabular has fewer columns in line than in definition
ERR_missingEndOfLine, ///< unused
ERR_closingUnopendEnv, ///< end{env} without corrresponding begin{env}
ERR_EnvNotClosed, ///< end{env} missing
ERR_unrecognizedKey, ///< in key/value argument, an unknown key is used
ERR_unrecognizedKeyValues, ///< in key/value argument, an unknown value is used for a key
ERR_commandOutsideEnv, ///< command used outside of designated environment (similar math command outside math)
ERR_spelling, ///< syntax error of text word (spell checker)
ERR_highlight, ///< arbitraty format for highlighting (math,verbatim,picture)
ERR_MAX // always last
};
/*!
* \brief info which is queued for syntaxchecking
*/
struct SyntaxLine {
StackEnvironment prevEnv; ///< environmentstack at start of line
TokenStack stack; ///< tokenstack at start of line (open arguments)
int ticket; ///< ticket number
bool clearOverlay; ///< clear syntax overlay, sometimes not necessary as it was done somewhere else
QDocumentLineHandle *dlh; ///< linehandle
int hint; ///< hint on lineNumber for faster look-up
bool initialRun;
};
/*!
* \brief structure to describe an syntax error
*/
struct Error {
QPair<int, int> range; ///< start,stop of error marker
ErrorType type; ///< type of error
int format; ///< arbitrary format to used instead of error marker
};
typedef QList<Error > Ranges;
explicit SyntaxCheck(QObject *parent = nullptr);
void putLine(QDocumentLineHandle *dlh, StackEnvironment previous, TokenStack stack, bool clearOverlay = false,int hint=-1);
void clearQueue();
void stop();
void setErrFormat(int errFormat);
QString getErrorAt(QDocumentLineHandle *dlh, int pos, StackEnvironment previous, TokenStack stack);
#ifndef NO_TESTS
void waitForQueueProcess(void);
#endif
int containsEnv(const QString &name, const StackEnvironment &envs, const int id = -1);
bool checkMathEnvActive(const StackEnvironment &envs);
int topEnv(const QString &name, const StackEnvironment &envs, const int id = -1);
bool checkCommand(const QString &cmd, const StackEnvironment &envs);
static bool equalEnvStack(StackEnvironment env1, StackEnvironment env2);
void setLtxCommands(QSharedPointer<LatexParser> cmds);
void setSpeller(SpellerUtility *su);
void setReplacementList(QMap<QString, QString> replacementList);
void setFormats(QMap<QString, int> formatList);
void enableSyntaxCheck(const bool enable);
void setHideNonTextGrammarErrors(const bool hide);
void setNonTextGrammarFormats(const QList<int> formats);
void markUnclosedEnv(Environment env);
signals:
void checkNextLine(QDocumentLineHandle *dlh, bool clearOverlay, int ticket, int hint); ///< enqueue next line for syntax checking as context has changed
protected:
void run();
void checkLine(const QString &line, Ranges &newRanges, StackEnvironment &activeEnv, QDocumentLineHandle *dlh, TokenList &tl, TokenStack stack, int ticket, int commentStart=-1);
private:
QQueue<SyntaxLine> mLines;
QSemaphore mLinesAvailable;
QMutex mLinesLock;
QAtomicInt mLinesEnqueuedCounter; //!< Total number of lines enqueued from beginning. Never decremented.
bool stopped;
bool mSyntaxChecking; //! show/hide syntax errors
int syntaxErrorFormat;
bool m_hideNonTextGrammarErrors=true;
QList<int> m_nonTextGrammarFormats,m_newNonTextGrammarFormats;
QSharedPointer<LatexParser> ltxCommands;
QSharedPointer<LatexParser> newLtxCommands;
bool newLtxCommandsAvailable;
QMutex mLtxCommandLock;
bool stackContainsDefinition(const TokenStack &stack) const;
SpellerUtility *speller,*newSpeller;
QMap<QString,QString> newReplacementList,mReplacementList;
QMap<QString,int> newFormatList,mFormatList;
};
#endif // SYNTAXCHECK_H