mirror of
				https://github.com/notepad-plus-plus/notepad-plus-plus.git
				synced 2025-10-31 03:24:04 +01:00 
			
		
		
		
	Update with https://www.scintilla.org/scintilla521.zip https://www.scintilla.org/lexilla515.zip - fix setting to bring Scintilla::PositionCR from ScintillaStructures.h inline with Sci_Position.h Sci_PositionCR - add workaround to enable lexer for searchResult commented out SCI_SETILEXER call on searchResult to get one result which is correctly handled by the lexer, added comment about the current problem with property @MarkingsStruct which seems to disappear after call to SCI_SETILEXER or CreateLexer - corrected usage of ObjC lexer - removed unnecessary filter stuff - use own sections for scintilla and lexilla build targets and allow parallel builds - as libscilex is no longer existing, changed to libscintilla - adapt makefiles and cmake - use VS2019 - started simple changes for createlexer adaptations, nullpointercheck missing on return of lexer name from deprecated LexerNameFromID -> undefined behaviour - movement from id -> lexer name, mostly done via LexerNameFromID + switching off corresponding compiler warning - changed to SCI_SETILEXER from SCI_SETLEXER, SCI_SETLEXERLANGUAGE needs to be corrected, see Scintilla5Migration.html - just commented out: SCI_LOADLEXERLIBRARY Fix #10504, close #11419
		
			
				
	
	
		
			394 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			394 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /******************************************************************
 | |
|  *  LexAsciidoc.cxx
 | |
|  *
 | |
|  *  A simple Asciidoc lexer for scintilla.
 | |
|  *
 | |
|  *  Based on the LexMarkdown.cxx by Jon Strait - jstrait@moonloop.net
 | |
|  *
 | |
|  *  The License.txt file describes the conditions under which this
 | |
|  *  software may be distributed.
 | |
|  *
 | |
|  *****************************************************************/
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <stdio.h>
 | |
| #include <stdarg.h>
 | |
| #include <assert.h>
 | |
| 
 | |
| #include <string>
 | |
| #include <string_view>
 | |
| 
 | |
| #include "ILexer.h"
 | |
| #include "Scintilla.h"
 | |
| #include "SciLexer.h"
 | |
| 
 | |
| #include "WordList.h"
 | |
| #include "LexAccessor.h"
 | |
| #include "Accessor.h"
 | |
| #include "StyleContext.h"
 | |
| #include "CharacterSet.h"
 | |
| #include "LexerModule.h"
 | |
| 
 | |
| using namespace Lexilla;
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| typedef struct {
 | |
|     bool start;
 | |
|     int len1;
 | |
|     int len2;
 | |
|     const char *name;
 | |
| } MacroItem;
 | |
| 
 | |
| static const MacroItem MacroList[] = {
 | |
|     // Directives
 | |
|     {true,  5, 2, "ifdef::"},
 | |
|     {true,  6, 2, "ifeval::"},
 | |
|     {true,  6, 2, "ifndef::"},
 | |
|     {true,  5, 2, "endif::"},
 | |
|     // Macros
 | |
|     {true,  5, 2, "audio::"},
 | |
|     {true,  7, 2, "include::"},
 | |
|     {true,  5, 2, "image::"},
 | |
|     {true,  5, 2, "video::"},
 | |
|     {false, 8, 1, "asciimath:"},
 | |
|     {false, 3, 1, "btn:"},
 | |
|     {false, 5, 1, "image:"},
 | |
|     {false, 3, 1, "kbd:"},
 | |
|     {false, 9, 1, "latexmath:"},
 | |
|     {false, 4, 1, "link:"},
 | |
|     {false, 6, 1, "mailto:"},
 | |
|     {false, 4, 1, "menu:"},
 | |
|     {false, 4, 1, "pass:"},
 | |
|     {false, 4, 1, "stem:"},
 | |
|     {false, 4, 1, "xref:"},
 | |
|     // Admonitions
 | |
|     {true,  7, 1, "CAUTION:"},
 | |
|     {true,  9, 1, "IMPORTANT:"},
 | |
|     {true,  4, 1, "NOTE:"},
 | |
|     {true,  3, 1, "TIP:"},
 | |
|     {true,  7, 1, "WARNING:"},
 | |
|     {false, 0, 0, NULL}
 | |
| };
 | |
| 
 | |
| constexpr bool IsNewline(const int ch) {
 | |
|     // sc.GetRelative(i) returns '\0' if out of range
 | |
|     return (ch == '\n' || ch == '\r' || ch == '\0');
 | |
| }
 | |
| 
 | |
| }
 | |
| 
 | |
| static bool AtTermStart(StyleContext &sc) {
 | |
|     return sc.currentPos == 0 || sc.chPrev == 0 || isspacechar(sc.chPrev);
 | |
| }
 | |
| 
 | |
| static void ColorizeAsciidocDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
 | |
|                                 WordList **, Accessor &styler) {
 | |
|     bool freezeCursor = false;
 | |
| 
 | |
|     StyleContext sc(startPos, static_cast<Sci_PositionU>(length), initStyle, styler);
 | |
| 
 | |
|     while (sc.More()) {
 | |
|         // Skip past escaped characters
 | |
|         if (sc.ch == '\\') {
 | |
|             sc.Forward();
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         // Skip newline.
 | |
|         if (IsNewline(sc.ch)) {
 | |
|             // Newline doesn't end blocks
 | |
|             if (sc.state != SCE_ASCIIDOC_CODEBK && \
 | |
|                 sc.state != SCE_ASCIIDOC_PASSBK && \
 | |
|                 sc.state != SCE_ASCIIDOC_COMMENTBK && \
 | |
|                 sc.state != SCE_ASCIIDOC_LITERALBK) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             sc.Forward();
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         // Conditional state-based actions
 | |
|         switch (sc.state) {
 | |
| 
 | |
|         // Strong
 | |
|         case SCE_ASCIIDOC_STRONG1:
 | |
|             if (sc.ch == '*' && sc.chPrev != ' ') {
 | |
|                 sc.Forward();
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|                 freezeCursor = true;
 | |
|             }
 | |
|             break;
 | |
|         case SCE_ASCIIDOC_STRONG2:
 | |
|             if (sc.Match("**") && sc.chPrev != ' ') {
 | |
|                 sc.Forward(2);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|                 freezeCursor = true;
 | |
|             }
 | |
|             break;
 | |
| 
 | |
|         // Emphasis
 | |
|         case SCE_ASCIIDOC_EM1:
 | |
|             if (sc.ch == '_' && sc.chPrev != ' ') {
 | |
|                 sc.Forward();
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|                 freezeCursor = true;
 | |
|             }
 | |
|             break;
 | |
|         case SCE_ASCIIDOC_EM2:
 | |
|             if (sc.Match("__") && sc.chPrev != ' ') {
 | |
|                 sc.Forward(2);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|                 freezeCursor = true;
 | |
|             }
 | |
|             break;
 | |
| 
 | |
|         // Link
 | |
|         case SCE_ASCIIDOC_LINK:
 | |
|             if (sc.ch == ']' && sc.chPrev != '\\') {
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             break;
 | |
| 
 | |
|         // Code block
 | |
|         case SCE_ASCIIDOC_CODEBK:
 | |
|             if (sc.atLineStart && sc.Match("----") && IsNewline(sc.GetRelative(4))) {
 | |
|                 sc.Forward(4);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             break;
 | |
| 
 | |
|         // Passthrough block
 | |
|         case SCE_ASCIIDOC_PASSBK:
 | |
|             if (sc.atLineStart && sc.Match("++++") && IsNewline(sc.GetRelative(4))) {
 | |
|                 sc.Forward(4);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             break;
 | |
| 
 | |
|         // Comment block
 | |
|         case SCE_ASCIIDOC_COMMENTBK:
 | |
|             if (sc.atLineStart && sc.Match("////") && IsNewline(sc.GetRelative(4))) {
 | |
|                 sc.Forward(4);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             break;
 | |
| 
 | |
|         // Literal
 | |
|         case SCE_ASCIIDOC_LITERAL:
 | |
|             if (sc.ch == '+' && sc.chPrev != '\\') {
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             break;
 | |
| 
 | |
|         // Literal block
 | |
|         case SCE_ASCIIDOC_LITERALBK:
 | |
|             if (sc.atLineStart && sc.Match("....") && IsNewline(sc.GetRelative(4))) {
 | |
|                 sc.Forward(4);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             break;
 | |
| 
 | |
|         // Attribute
 | |
|         case SCE_ASCIIDOC_ATTRIB:
 | |
|             if (sc.ch == ':' && sc.chPrev != ' ' && sc.chNext == ' ') {
 | |
|                 sc.Forward();
 | |
|                 sc.SetState(SCE_ASCIIDOC_ATTRIBVAL);
 | |
|             }
 | |
|             break;
 | |
| 
 | |
|         // Macro
 | |
|         case SCE_ASCIIDOC_MACRO:
 | |
|             if (sc.ch == ']' && sc.chPrev != '\\') {
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             break;
 | |
| 
 | |
|         // Default
 | |
|         case SCE_ASCIIDOC_DEFAULT:
 | |
|             // Headers
 | |
|             if (sc.atLineStart && sc.Match("====== ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_HEADER6);
 | |
|                 sc.Forward(6);
 | |
|             }
 | |
|             else if (sc.atLineStart && sc.Match("===== ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_HEADER5);
 | |
|                 sc.Forward(5);
 | |
|             }
 | |
|             else if (sc.atLineStart && sc.Match("==== ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_HEADER4);
 | |
|                 sc.Forward(4);
 | |
|             }
 | |
|             else if (sc.atLineStart && sc.Match("=== ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_HEADER3);
 | |
|                 sc.Forward(3);
 | |
|             }
 | |
|             else if (sc.atLineStart && sc.Match("== ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_HEADER2);
 | |
|                 sc.Forward(2);
 | |
|             }
 | |
|             else if (sc.atLineStart && sc.Match("= ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_HEADER1);
 | |
|                 sc.Forward(1);
 | |
|             }
 | |
|             // Unordered list item
 | |
|             else if (sc.atLineStart && sc.Match("****** ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);
 | |
|                 sc.Forward(6);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             else if (sc.atLineStart && sc.Match("***** ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);
 | |
|                 sc.Forward(5);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             else if (sc.atLineStart && sc.Match("**** ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);
 | |
|                 sc.Forward(4);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             else if (sc.atLineStart && sc.Match("*** ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);
 | |
|                 sc.Forward(3);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             else if (sc.atLineStart && sc.Match("** ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);
 | |
|                 sc.Forward(2);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             else if (sc.atLineStart && sc.Match("* ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);
 | |
|                 sc.Forward(1);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             // Ordered list item
 | |
|             else if (sc.atLineStart && sc.Match("...... ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);
 | |
|                 sc.Forward(6);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             else if (sc.atLineStart && sc.Match("..... ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);
 | |
|                 sc.Forward(5);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             else if (sc.atLineStart && sc.Match(".... ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);
 | |
|                 sc.Forward(4);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             else if (sc.atLineStart && sc.Match("... ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);
 | |
|                 sc.Forward(3);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             else if (sc.atLineStart && sc.Match(".. ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);
 | |
|                 sc.Forward(2);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             else if (sc.atLineStart && sc.Match(". ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);
 | |
|                 sc.Forward(1);
 | |
|                 sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|             }
 | |
|             // Blockquote
 | |
|             else if (sc.atLineStart && sc.Match("> ")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_BLOCKQUOTE);
 | |
|                 sc.Forward();
 | |
|             }
 | |
|             // Link
 | |
|             else if (!sc.atLineStart && sc.ch == '[' && sc.chPrev != '\\' && sc.chNext != ' ') {
 | |
|                 sc.Forward();
 | |
|                 sc.SetState(SCE_ASCIIDOC_LINK);
 | |
|                 freezeCursor = true;
 | |
|             }
 | |
|             // Code block
 | |
|             else if (sc.atLineStart && sc.Match("----") && IsNewline(sc.GetRelative(4))) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_CODEBK);
 | |
|                 sc.Forward(4);
 | |
|             }
 | |
|             // Passthrough block
 | |
|             else if (sc.atLineStart && sc.Match("++++") && IsNewline(sc.GetRelative(4))) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_PASSBK);
 | |
|                 sc.Forward(4);
 | |
|             }
 | |
|             // Comment block
 | |
|             else if (sc.atLineStart && sc.Match("////") && IsNewline(sc.GetRelative(4))) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_COMMENTBK);
 | |
|                 sc.Forward(4);
 | |
|             }
 | |
|             // Comment
 | |
|             else if (sc.atLineStart && sc.Match("//")) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_COMMENT);
 | |
|                 sc.Forward();
 | |
|             }
 | |
|             // Literal
 | |
|             else if (sc.ch == '+' && sc.chPrev != '\\' && sc.chNext != ' ' && AtTermStart(sc)) {
 | |
|                 sc.Forward();
 | |
|                 sc.SetState(SCE_ASCIIDOC_LITERAL);
 | |
|                 freezeCursor = true;
 | |
|             }
 | |
|             // Literal block
 | |
|             else if (sc.atLineStart && sc.Match("....") && IsNewline(sc.GetRelative(4))) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_LITERALBK);
 | |
|                 sc.Forward(4);
 | |
|             }
 | |
|             // Attribute
 | |
|             else if (sc.atLineStart && sc.ch == ':' && sc.chNext != ' ') {
 | |
|                 sc.SetState(SCE_ASCIIDOC_ATTRIB);
 | |
|             }
 | |
|             // Strong
 | |
|             else if (sc.Match("**") && sc.GetRelative(2) != ' ') {
 | |
|                 sc.SetState(SCE_ASCIIDOC_STRONG2);
 | |
|                 sc.Forward();
 | |
|             }
 | |
|             else if (sc.ch == '*' && sc.chNext != ' ' && AtTermStart(sc)) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_STRONG1);
 | |
|             }
 | |
|             // Emphasis
 | |
|             else if (sc.Match("__") && sc.GetRelative(2) != ' ') {
 | |
|                 sc.SetState(SCE_ASCIIDOC_EM2);
 | |
|                 sc.Forward();
 | |
|             }
 | |
|             else if (sc.ch == '_' && sc.chNext != ' ' && AtTermStart(sc)) {
 | |
|                 sc.SetState(SCE_ASCIIDOC_EM1);
 | |
|             }
 | |
|             // Macro
 | |
|             else if (sc.atLineStart && sc.ch == '[' && sc.chNext != ' ') {
 | |
|                 sc.Forward();
 | |
|                 sc.SetState(SCE_ASCIIDOC_MACRO);
 | |
|                 freezeCursor = true;
 | |
|             }
 | |
|             else {
 | |
|                 int i = 0;
 | |
|                 bool found = false;
 | |
|                 while (!found && MacroList[i].name != NULL) {
 | |
|                     if (MacroList[i].start)
 | |
|                         found = sc.atLineStart && sc.Match(MacroList[i].name);
 | |
|                     else
 | |
|                         found = sc.Match(MacroList[i].name);
 | |
|                     if (found) {
 | |
|                         sc.SetState(SCE_ASCIIDOC_MACRO);
 | |
|                         sc.Forward(MacroList[i].len1);
 | |
|                         sc.SetState(SCE_ASCIIDOC_DEFAULT);
 | |
|                         if (MacroList[i].len2 > 1)
 | |
|                             sc.Forward(MacroList[i].len2 - 1);
 | |
|                     }
 | |
|                     i++;
 | |
|                 }
 | |
|             }
 | |
|             break;
 | |
|         }
 | |
|         // Advance if not holding back the cursor for this iteration.
 | |
|         if (!freezeCursor)
 | |
|             sc.Forward();
 | |
|         freezeCursor = false;
 | |
|     }
 | |
|     sc.Complete();
 | |
| }
 | |
| 
 | |
| LexerModule lmAsciidoc(SCLEX_ASCIIDOC, ColorizeAsciidocDoc, "asciidoc");
 |