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