1 // Scintilla source code edit control
2 // Copyright 1998-2001 by Neil Hodgson <[email protected]>
3 // The License.txt file describes the conditions under which this software may be distributed.
4
5 //用于解析LRC歌词
6
7 #include <stdlib.h>
8 #include <string>
9 #include <stdio.h>
10 #include <stdarg.h>
11 #include <assert.h>
12 #include <ctype.h>
13 #include <string_view>
14
15 #include "ILexer.h"
16 #include "Scintilla.h"
17 #include "SciLexer.h"
18
19 #include "WordList.h"
20 #include "LexAccessor.h"
21 #include "Accessor.h"
22 #include "StyleContext.h"
23 #include "CharacterSet.h"
24 #include "LexerModule.h"
25
26 using namespace Scintilla;
27 using std::string_view;
28
29
AtEOL(Accessor & styler,Sci_PositionU i)30 static inline bool AtEOL(Accessor &styler, Sci_PositionU i) {
31 return (styler[i] == '\n') ||
32 ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
33 }
34
IsLetterOrNumber(int ch)35 static inline bool IsLetterOrNumber(int ch)
36 {
37 return ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'));
38 }
39
40
ColouriseMakeLine(char * lineBuffer,Sci_PositionU lengthLine,Sci_PositionU startLine,Sci_PositionU endPos,Accessor & styler,WordList * keywordlists[])41 static void ColouriseMakeLine(char *lineBuffer, Sci_PositionU lengthLine, Sci_PositionU startLine, Sci_PositionU endPos, Accessor &styler, WordList* keywordlists[])
42 {
43 WordList &keywords = *keywordlists[0];
44 string_view strBuff{ lineBuffer };
45 styler.ColourTo(startLine - 1, SCE_LYRIC_DEFAULT);
46
47 int i = 0;
48 int curStyle = SCE_LYRIC_DEFAULT;
49 int tag_start_pos{ -1 };
50 int tag_end_pos{ -1 };
51 int separator_end{ -1 };
52 for (auto ch : strBuff)
53 {
54 if (ch == '[')
55 {
56 tag_start_pos = i;
57 styler.ColourTo(startLine + i - 1, curStyle);
58 curStyle = SCE_LYRIC_TIMETAG;
59 }
60 if (ch == ':')
61 {
62 std::string str{ strBuff.substr(tag_start_pos + 1, i - tag_start_pos - 1) };
63
64 if (keywords.InList(str.c_str()))
65 {
66 styler.ColourTo(startLine + tag_start_pos, curStyle);
67 curStyle = SCE_LYRIC_TIME_TAG_KEYWORD;
68 styler.ColourTo(startLine + i - 1, curStyle);
69 curStyle = SCE_LYRIC_TIMETAG;
70 }
71 }
72 if (ch == ']')
73 {
74 tag_end_pos = i;
75 styler.ColourTo(startLine + i, curStyle);
76 curStyle = SCE_LYRIC_TEXT;
77 }
78 if (i > 2 && lineBuffer[i - 2] == ' ' && lineBuffer[i - 1] == '/' && lineBuffer[i] == ' ')
79 {
80 separator_end = i;
81 styler.ColourTo(startLine + i - 3, curStyle);
82 curStyle = SCE_LYRIC_SEPARATOR;
83 styler.ColourTo(startLine + i, curStyle);
84 curStyle = SCE_LYRIC_TRANSLATION;
85 }
86
87 i++;
88 }
89 styler.ColourTo(endPos, curStyle);
90
91 }
92
ColouriseLyricDoc(Sci_PositionU startPos,Sci_Position length,int,WordList * keywordlists[],Accessor & styler)93 static void ColouriseLyricDoc(Sci_PositionU startPos, Sci_Position length, int, WordList* keywordlists[],
94 Accessor &styler) {
95 char lineBuffer[1024];
96 styler.StartAt(startPos);
97 styler.StartSegment(startPos);
98 Sci_PositionU linePos = 0;
99 Sci_PositionU startLine = startPos;
100 for (Sci_PositionU i = startPos; i < startPos + length; i++) {
101 lineBuffer[linePos++] = styler[i];
102 if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
103 // End of line (or of line buffer) met, colourise it
104 lineBuffer[linePos] = '\0';
105 ColouriseMakeLine(lineBuffer, linePos, startLine, i, styler, keywordlists);
106 linePos = 0;
107 startLine = i + 1;
108 }
109 }
110 if (linePos > 0) { // Last line does not have ending characters
111 ColouriseMakeLine(lineBuffer, linePos, startLine, startPos + length - 1, styler, keywordlists);
112 }
113 }
114
115 LexerModule lmLyric(SCLEX_LYRIC, ColouriseLyricDoc, "Lyric");
116