diff options
| -rw-r--r-- | doc/ScintillaHistory.html | 1 | ||||
| -rw-r--r-- | gtk/makefile | 13 | ||||
| -rw-r--r-- | gtk/scintilla.mak | 3 | ||||
| -rw-r--r-- | include/SciLexer.h | 23 | ||||
| -rw-r--r-- | include/Scintilla.iface | 25 | ||||
| -rw-r--r-- | macosx/makefile | 13 | ||||
| -rw-r--r-- | src/KeyWords.cxx | 1 | ||||
| -rw-r--r-- | src/LexMarkdown.cxx | 412 | ||||
| -rw-r--r-- | vcbuild/SciLexer.dsp | 4 | ||||
| -rw-r--r-- | win32/makefile | 13 | ||||
| -rw-r--r-- | win32/scintilla.mak | 3 | ||||
| -rw-r--r-- | win32/scintilla_vc6.mak | 3 | 
12 files changed, 496 insertions, 18 deletions
| diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index c36f7fbda..cedee70a9 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -339,6 +339,7 @@  	<td>Eric Kidd</td>  	<td>maXmo</td>  	<td>David Severwright</td> +	<td>Jon Strait</td>      </tr>      </table>      <p> diff --git a/gtk/makefile b/gtk/makefile index 6fa7c8042..bec506007 100644 --- a/gtk/makefile +++ b/gtk/makefile @@ -68,12 +68,13 @@ LexBaan.o LexBash.o LexBasic.o LexBullant.o LexCaml.o LexCLW.o LexCmake.o \  LexCOBOL.o LexConf.o LexCPP.o LexCrontab.o LexCsound.o LexCSS.o LexD.o \  LexEiffel.o LexErlang.o LexEScript.o LexFlagship.o LexForth.o LexFortran.o \  LexGAP.o LexGui4Cli.o LexHaskell.o LexHTML.o LexInno.o LexKix.o LexLisp.o \ -LexLout.o LexLua.o LexMagik.o LexMatlab.o LexMetapost.o LexMMIXAL.o LexMPT.o \ -LexMSSQL.o LexMySQL.o LexNimrod.o LexNsis.o LexOpal.o LexOthers.o LexPascal.o \ -LexPB.o LexPerl.o LexPLM.o LexPOV.o LexPowerPro.o LexPowerShell.o \ -LexProgress.o LexPS.o LexPython.o LexR.o LexRebol.o LexRuby.o LexScriptol.o \ -LexSmalltalk.o LexSML.o LexSorcus.o LexSpecman.o LexSpice.o LexSQL.o LexTACL.o \ -LexTADS3.o LexTAL.o LexTCL.o LexTeX.o LexVB.o LexVerilog.o LexVHDL.o LexYAML.o +LexLout.o LexLua.o LexMagik.o LexMarkdown.o LexMatlab.o LexMetapost.o \ +LexMMIXAL.o LexMPT.o LexMSSQL.o LexMySQL.o LexNimrod.o LexNsis.o LexOpal.o \ +LexOthers.o LexPascal.o LexPB.o LexPerl.o LexPLM.o LexPOV.o LexPowerPro.o \ +LexPowerShell.o LexProgress.o LexPS.o LexPython.o LexR.o LexRebol.o LexRuby.o \ +LexScriptol.o LexSmalltalk.o LexSML.o LexSorcus.o LexSpecman.o LexSpice.o \ +LexSQL.o LexTACL.o LexTADS3.o LexTAL.o LexTCL.o LexTeX.o LexVB.o LexVerilog.o \ +LexVHDL.o LexYAML.o  #--Autogenerated -- end of automatically generated section  all: $(COMPLIB) diff --git a/gtk/scintilla.mak b/gtk/scintilla.mak index 39dd20a9d..d7ca81e0e 100644 --- a/gtk/scintilla.mak +++ b/gtk/scintilla.mak @@ -182,6 +182,7 @@ LEXOBJS=\  	$(DIR_O)\LexLout.obj \  	$(DIR_O)\LexLua.obj \  	$(DIR_O)\LexMagik.obj \ +	$(DIR_O)\LexMarkdown.obj \  	$(DIR_O)\LexMatlab.obj \  	$(DIR_O)\LexMetapost.obj \  	$(DIR_O)\LexMMIXAL.obj \ @@ -440,6 +441,8 @@ $(DIR_O)\LexLua.obj: ..\src\LexLua.cxx $(LEX_HEADERS)  $(DIR_O)\LexMagik.obj: ..\src\LexMagik.cxx $(LEX_HEADERS) +$(DIR_O)\LexMarkdown.obj: ..\src\LexMarkdown.cxx $(LEX_HEADERS) +  $(DIR_O)\LexMatlab.obj: ..\src\LexMatlab.cxx $(LEX_HEADERS)  $(DIR_O)\LexMetapost.obj: ..\src\LexMetapost.cxx $(LEX_HEADERS) diff --git a/include/SciLexer.h b/include/SciLexer.h index e741ff486..2800617b5 100644 --- a/include/SciLexer.h +++ b/include/SciLexer.h @@ -110,6 +110,7 @@  #define SCLEX_POWERPRO 95  #define SCLEX_NIMROD 96  #define SCLEX_SML 97 +#define SCLEX_MARKDOWN 98  #define SCLEX_AUTOMATIC 1000  #define SCE_P_DEFAULT 0  #define SCE_P_COMMENTLINE 1 @@ -1343,6 +1344,28 @@  #define SCE_SML_COMMENT1 13  #define SCE_SML_COMMENT2 14  #define SCE_SML_COMMENT3 15 +#define SCE_MARKDOWN_DEFAULT 0 +#define SCE_MARKDOWN_LINE_BEGIN 1 +#define SCE_MARKDOWN_STRONG1 2 +#define SCE_MARKDOWN_STRONG2 3 +#define SCE_MARKDOWN_EM1 4 +#define SCE_MARKDOWN_EM2 5 +#define SCE_MARKDOWN_HEADER1 6 +#define SCE_MARKDOWN_HEADER2 7 +#define SCE_MARKDOWN_HEADER3 8 +#define SCE_MARKDOWN_HEADER4 9 +#define SCE_MARKDOWN_HEADER5 10 +#define SCE_MARKDOWN_HEADER6 11 +#define SCE_MARKDOWN_PRECHAR 12 +#define SCE_MARKDOWN_ULIST_ITEM 13 +#define SCE_MARKDOWN_OLIST_ITEM 14 +#define SCE_MARKDOWN_BLOCKQUOTE 15 +#define SCE_MARKDOWN_STRIKEOUT 16 +#define SCE_MARKDOWN_HRULE 17 +#define SCE_MARKDOWN_LINK 18 +#define SCE_MARKDOWN_CODE 19 +#define SCE_MARKDOWN_CODE2 20 +#define SCE_MARKDOWN_CODEBK 21  /* --Autogenerated -- end of section automatically generated from Scintilla.iface */  #endif diff --git a/include/Scintilla.iface b/include/Scintilla.iface index d2682a18e..ee7ba0ba1 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -2247,6 +2247,7 @@ val SCLEX_SORCUS=94  val SCLEX_POWERPRO=95  val SCLEX_NIMROD=96  val SCLEX_SML=97 +val SCLEX_MARKDOWN=98  # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a  # value assigned in sequence from SCLEX_AUTOMATIC+1. @@ -3657,6 +3658,30 @@ val SCE_SML_COMMENT=12  val SCE_SML_COMMENT1=13  val SCE_SML_COMMENT2=14  val SCE_SML_COMMENT3=15 +# Lexical state for SCLEX_MARKDOWN +lex Markdown=SCLEX_MARKDOWN SCE_MARKDOWN_ +val SCE_MARKDOWN_DEFAULT=0 +val SCE_MARKDOWN_LINE_BEGIN=1 +val SCE_MARKDOWN_STRONG1=2 +val SCE_MARKDOWN_STRONG2=3 +val SCE_MARKDOWN_EM1=4 +val SCE_MARKDOWN_EM2=5 +val SCE_MARKDOWN_HEADER1=6 +val SCE_MARKDOWN_HEADER2=7 +val SCE_MARKDOWN_HEADER3=8 +val SCE_MARKDOWN_HEADER4=9 +val SCE_MARKDOWN_HEADER5=10 +val SCE_MARKDOWN_HEADER6=11 +val SCE_MARKDOWN_PRECHAR=12 +val SCE_MARKDOWN_ULIST_ITEM=13 +val SCE_MARKDOWN_OLIST_ITEM=14 +val SCE_MARKDOWN_BLOCKQUOTE=15 +val SCE_MARKDOWN_STRIKEOUT=16 +val SCE_MARKDOWN_HRULE=17 +val SCE_MARKDOWN_LINK=18 +val SCE_MARKDOWN_CODE=19 +val SCE_MARKDOWN_CODE2=20 +val SCE_MARKDOWN_CODEBK=21  # Events diff --git a/macosx/makefile b/macosx/makefile index f4774e231..1a1524bb9 100644 --- a/macosx/makefile +++ b/macosx/makefile @@ -68,12 +68,13 @@ LexBaan.o LexBash.o LexBasic.o LexBullant.o LexCaml.o LexCLW.o LexCmake.o \  LexCOBOL.o LexConf.o LexCPP.o LexCrontab.o LexCsound.o LexCSS.o LexD.o \  LexEiffel.o LexErlang.o LexEScript.o LexFlagship.o LexForth.o LexFortran.o \  LexGAP.o LexGui4Cli.o LexHaskell.o LexHTML.o LexInno.o LexKix.o LexLisp.o \ -LexLout.o LexLua.o LexMagik.o LexMatlab.o LexMetapost.o LexMMIXAL.o LexMPT.o \ -LexMSSQL.o LexMySQL.o LexNimrod.o LexNsis.o LexOpal.o LexOthers.o LexPascal.o \ -LexPB.o LexPerl.o LexPLM.o LexPOV.o LexPowerPro.o LexPowerShell.o \ -LexProgress.o LexPS.o LexPython.o LexR.o LexRebol.o LexRuby.o LexScriptol.o \ -LexSmalltalk.o LexSML.o LexSorcus.o LexSpecman.o LexSpice.o LexSQL.o LexTACL.o \ -LexTADS3.o LexTAL.o LexTCL.o LexTeX.o LexVB.o LexVerilog.o LexVHDL.o LexYAML.o +LexLout.o LexLua.o LexMagik.o LexMarkdown.o LexMatlab.o LexMetapost.o \ +LexMMIXAL.o LexMPT.o LexMSSQL.o LexMySQL.o LexNimrod.o LexNsis.o LexOpal.o \ +LexOthers.o LexPascal.o LexPB.o LexPerl.o LexPLM.o LexPOV.o LexPowerPro.o \ +LexPowerShell.o LexProgress.o LexPS.o LexPython.o LexR.o LexRebol.o LexRuby.o \ +LexScriptol.o LexSmalltalk.o LexSML.o LexSorcus.o LexSpecman.o LexSpice.o \ +LexSQL.o LexTACL.o LexTADS3.o LexTAL.o LexTCL.o LexTeX.o LexVB.o LexVerilog.o \ +LexVHDL.o LexYAML.o  #--Autogenerated -- end of automatically generated section  # The LEXOBJS have to be treated specially as the functions in them are not called from external code diff --git a/src/KeyWords.cxx b/src/KeyWords.cxx index 366cb47dc..5e4de668d 100644 --- a/src/KeyWords.cxx +++ b/src/KeyWords.cxx @@ -375,6 +375,7 @@ int Scintilla_LinkLexers() {  	LINK_LEXER(lmLua);  	LINK_LEXER(lmMagikSF);  	LINK_LEXER(lmMake); +	LINK_LEXER(lmMarkdown);  	LINK_LEXER(lmMatlab);  	LINK_LEXER(lmMETAPOST);  	LINK_LEXER(lmMMIXAL); diff --git a/src/LexMarkdown.cxx b/src/LexMarkdown.cxx new file mode 100644 index 000000000..f7fc48f40 --- /dev/null +++ b/src/LexMarkdown.cxx @@ -0,0 +1,412 @@ +/****************************************************************** + *  LexMarkdown.cxx + * + *  A simple Markdown lexer for scintilla. + *    + *  Includes highlighting for some extra features from the + *  Pandoc implementation; strikeout, using '#.' as a default  + *  ordered list item marker, and delimited code blocks. + *  + *  Limitations: + *  + *  Standard indented code blocks are not highlighted at all, + *  as it would conflict with other indentation schemes. Use  + *  delimited code blocks for blanket highlighting of an + *  entire code block.  Embedded HTML is not highlighted either. + *  Blanket HTML highlighting has issues, because some Markdown + *  implementations allow Markdown markup inside of the HTML. Also, + *  there is a following blank line issue that can't be ignored,  + *  explained in the next paragraph. Embedded HTML and code  + *  blocks would be better supported with language specific  + *  highlighting. + *  + *  The highlighting aims to accurately reflect correct syntax, + *  but a few restrictions are relaxed. Delimited code blocks are + *  highlighted, even if the line following the code block is not blank.   + *  Requiring a blank line after a block, breaks the highlighting + *  in certain cases, because of the way Scintilla ends up calling + *  the lexer. + *  + *  Written 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 <ctype.h> +#include <stdio.h> +#include <stdarg.h> + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "StyleContext.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + +static inline bool IsNewline(const int ch) { +    return (ch == '\n' || ch == '\r'); +} + +// True if can follow ch down to the end with possibly trailing whitespace +static bool FollowToLineEnd(const int ch, const int state, const unsigned int endPos, StyleContext &sc) { +    unsigned int i = 0; +    while (sc.GetRelative(++i) == ch) +        ; +    // Skip over whitespace +    while (IsASpaceOrTab(sc.GetRelative(i)) && sc.currentPos + i < endPos) +        ++i; +    if (IsNewline(sc.GetRelative(i)) || sc.currentPos + i == endPos) { +        sc.Forward(i); +        sc.ChangeState(state); +        sc.SetState(SCE_MARKDOWN_LINE_BEGIN); +        return true; +    } +    else return false; +} + +// Set the state on text section from current to length characters,  +// then set the rest until the newline to default, except for any characters matching token +static void SetStateAndZoom(const int state, const int length, const int token, StyleContext &sc) { +    sc.SetState(state); +    sc.Forward(length); +    sc.SetState(SCE_MARKDOWN_DEFAULT); +    sc.Forward(); +    bool started = false; +    while (sc.More() && !IsNewline(sc.ch)) { +        if (sc.ch == token && !started) { +            sc.SetState(state); +            started = true; +        } +        else if (sc.ch != token) { +            sc.SetState(SCE_MARKDOWN_DEFAULT); +            started = false; +        } +        sc.Forward(); +    } +    sc.SetState(SCE_MARKDOWN_LINE_BEGIN); +} + +// Does the previous line have more than spaces and tabs? +static bool HasPrevLineContent(StyleContext &sc) { +    int i = 0; +    // Go back to the previous newline +    while ((--i + sc.currentPos) && !IsNewline(sc.GetRelative(i)))  +        ; +    while (--i + sc.currentPos) { +        if (IsNewline(sc.GetRelative(i))) +            break; +        if (!IsASpaceOrTab(sc.GetRelative(i))) +            return true; +    } +    return false; +} + +static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) { +    int c, count = 1; +    unsigned int i = 0; +    while (++i) { +        c = sc.GetRelative(i); +        if (c == sc.ch)  +            ++count; +        // hit a terminating character +        else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) { +            // Are we a valid HRULE +            if ((IsNewline(c) || sc.currentPos + i == endPos) &&  +                    count >= 3 && !HasPrevLineContent(sc)) { +                sc.SetState(SCE_MARKDOWN_HRULE); +                sc.Forward(i); +                sc.SetState(SCE_MARKDOWN_LINE_BEGIN); +                return true; +            } +            else { +                sc.SetState(SCE_MARKDOWN_DEFAULT); +		return false; +            } +        } +    } +    return false; +} + +static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle, +                               WordList **, Accessor &styler) { +    unsigned int endPos = startPos + length; +    int precharCount = 0; +    // Don't advance on a new loop iteration and retry at the same position. +    // Useful in the corner case of having to start at the beginning file position +    // in the default state. +    bool freezeCursor = false; +     +    StyleContext sc(startPos, length, initStyle, styler); + +    while (sc.More()) { +        // Skip past escaped characters +        if (sc.ch == '\\') { +            sc.Forward(); +            continue; +        } +         +        // A blockquotes resets the line semantics +        if (sc.state == SCE_MARKDOWN_BLOCKQUOTE) +            sc.SetState(SCE_MARKDOWN_LINE_BEGIN); +         +        // Conditional state-based actions +        if (sc.state == SCE_MARKDOWN_CODE2) { +            if (sc.Match("``") && sc.GetRelative(-2) != ' ') { +                sc.Forward(2); +                sc.SetState(SCE_MARKDOWN_DEFAULT); +            } +        }     +        else if (sc.state == SCE_MARKDOWN_CODE) { +            if (sc.ch == '`' && sc.chPrev != ' ') +                sc.ForwardSetState(SCE_MARKDOWN_DEFAULT); +        } +        /* De-activated because it gets in the way of other valid indentation +         * schemes, for example multiple paragraphs inside a list item. +        // Code block +        else if (sc.state == SCE_MARKDOWN_CODEBK) { +            bool d = true; +            if (IsNewline(sc.ch)) { +                if (sc.chNext != '\t') { +                    for (int c = 1; c < 5; ++c) { +                        if (sc.GetRelative(c) != ' ') +                            d = false; +                    } +                } +            } +            else if (sc.atLineStart) { +                if (sc.ch != '\t' ) { +                    for (int i = 0; i < 4; ++i) { +                        if (sc.GetRelative(i) != ' ') +                            d = false; +                    } +                } +            } +            if (!d) +                sc.SetState(SCE_MARKDOWN_LINE_BEGIN); +        } +        */ +        // Strong +        else if (sc.state == SCE_MARKDOWN_STRONG1) { +            if (sc.Match("**") && sc.chPrev != ' ') { +                sc.Forward(2); +                sc.SetState(SCE_MARKDOWN_DEFAULT); +            } +        }  +        else if (sc.state == SCE_MARKDOWN_STRONG2) {   +            if (sc.Match("__") && sc.chPrev != ' ') {   +                sc.Forward(2); +                sc.SetState(SCE_MARKDOWN_DEFAULT); +            } +        } +        // Emphasis     +        else if (sc.state == SCE_MARKDOWN_EM1) { +            if (sc.ch == '*' && sc.chPrev != ' ') +                sc.ForwardSetState(SCE_MARKDOWN_DEFAULT); +        } +        else if (sc.state == SCE_MARKDOWN_EM2) { +            if (sc.ch == '_' && sc.chPrev != ' ') +                sc.ForwardSetState(SCE_MARKDOWN_DEFAULT); +        } +        else if (sc.state == SCE_MARKDOWN_CODEBK) { +            if (sc.atLineStart && sc.Match("~~~")) { +                int i = 1; +                while (!IsNewline(sc.GetRelative(i)) && sc.currentPos + i < endPos) +                    i++; +                sc.Forward(i); +                sc.SetState(SCE_MARKDOWN_DEFAULT); +            } +        } +        else if (sc.state == SCE_MARKDOWN_STRIKEOUT) { +            if (sc.Match("~~") && sc.chPrev != ' ') { +                sc.Forward(2); +                sc.SetState(SCE_MARKDOWN_DEFAULT); +            } +        } +        else if (sc.state == SCE_MARKDOWN_LINE_BEGIN) { +            // Header +            if (sc.Match("######")) +                SetStateAndZoom(SCE_MARKDOWN_HEADER6, 6, '#', sc); +            else if (sc.Match("#####")) +                SetStateAndZoom(SCE_MARKDOWN_HEADER5, 5, '#', sc); +            else if (sc.Match("####")) +                SetStateAndZoom(SCE_MARKDOWN_HEADER4, 4, '#', sc); +            else if (sc.Match("###")) +                SetStateAndZoom(SCE_MARKDOWN_HEADER3, 3, '#', sc); +            else if (sc.Match("##")) +                SetStateAndZoom(SCE_MARKDOWN_HEADER2, 2, '#', sc); +            else if (sc.Match("#")) { +                // Catch the special case of an unordered list +                if (sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) { +                    precharCount = 0; +                    sc.SetState(SCE_MARKDOWN_PRECHAR); +                } +                else +                    SetStateAndZoom(SCE_MARKDOWN_HEADER1, 1, '#', sc); +            } +            // Code block +            else if (sc.Match("~~~")) { +                if (!HasPrevLineContent(sc)) +                    sc.SetState(SCE_MARKDOWN_CODEBK); +                else +                    sc.SetState(SCE_MARKDOWN_DEFAULT); +            } +            else if (sc.ch == '=') { +                if (HasPrevLineContent(sc) && FollowToLineEnd('=', SCE_MARKDOWN_HEADER1, endPos, sc)) +                    ; +                else +                    sc.SetState(SCE_MARKDOWN_DEFAULT); +            } +            else if (sc.ch == '-') { +                if (HasPrevLineContent(sc) && FollowToLineEnd('-', SCE_MARKDOWN_HEADER2, endPos, sc)) +                    ; +                else { +                    precharCount = 0; +                    sc.SetState(SCE_MARKDOWN_PRECHAR); +                } +            } +            else if (IsNewline(sc.ch)) +                sc.SetState(SCE_MARKDOWN_LINE_BEGIN); +            else { +                precharCount = 0; +                sc.SetState(SCE_MARKDOWN_PRECHAR); +            } +        } +                 +        // The header lasts until the newline +        else if (sc.state == SCE_MARKDOWN_HEADER1 || sc.state == SCE_MARKDOWN_HEADER2 || +                sc.state == SCE_MARKDOWN_HEADER3 || sc.state == SCE_MARKDOWN_HEADER4 || +                sc.state == SCE_MARKDOWN_HEADER5 || sc.state == SCE_MARKDOWN_HEADER6) { +            if (IsNewline(sc.ch)) +                sc.SetState(SCE_MARKDOWN_LINE_BEGIN); +        } +         +        // New state only within the initial whitespace +        if (sc.state == SCE_MARKDOWN_PRECHAR) { +            // Blockquote +            if (sc.ch == '>' && precharCount < 5) +                sc.SetState(SCE_MARKDOWN_BLOCKQUOTE); +            /* +            // Begin of code block +            else if (!HasPrevLineContent(sc) && (sc.chPrev == '\t' || precharCount >= 4)) +                sc.SetState(SCE_MARKDOWN_CODEBK); +            */ +            // HRule - Total of three or more hyphens, asterisks, or underscores  +            // on a line by themselves     +            else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '_') && IsValidHrule(endPos, sc)) +                ; +            // Unordered list +            else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '+') && IsASpaceOrTab(sc.chNext)) { +                sc.SetState(SCE_MARKDOWN_ULIST_ITEM); +                sc.ForwardSetState(SCE_MARKDOWN_DEFAULT); +            } +            // Ordered list +            else if (IsADigit(sc.ch)) { +                int digitCount = 0; +                while (IsADigit(sc.GetRelative(++digitCount))) +                    ; +                if (sc.GetRelative(digitCount) == '.' &&  +                        IsASpaceOrTab(sc.GetRelative(digitCount + 1))) { +                    sc.SetState(SCE_MARKDOWN_OLIST_ITEM); +                    sc.Forward(digitCount + 1); +                    sc.SetState(SCE_MARKDOWN_DEFAULT); +                } +            } +            // Alternate Ordered list +            else if (sc.ch == '#' && sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) { +                sc.SetState(SCE_MARKDOWN_OLIST_ITEM); +                sc.Forward(2); +                sc.SetState(SCE_MARKDOWN_DEFAULT); +            } +            else if (sc.ch != ' ' || precharCount > 2) +                sc.SetState(SCE_MARKDOWN_DEFAULT); +            else +                ++precharCount; +        } +         +        // New state anywhere in doc +        if (sc.state == SCE_MARKDOWN_DEFAULT) { +            if (sc.atLineStart && sc.ch == '#') { +                sc.SetState(SCE_MARKDOWN_LINE_BEGIN); +                freezeCursor = true; +            } +            // Links and Images +            if (sc.Match("![") || sc.ch == '[') { +                int i = 0, j = 0, k = 0; +                int len = endPos - sc.currentPos; +                while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\')) +                    ; +                if (sc.GetRelative(i) == ']') { +                    j = i; +                    if (sc.GetRelative(++i) == '(') { +                        while (i < len && (sc.GetRelative(++i) != ')' || sc.GetRelative(i - 1) == '\\')) +                            ; +                        if (sc.GetRelative(i) == ')') +                            k = i; +                    } +                    else if (sc.GetRelative(i) == '[' || sc.GetRelative(++i) == '[') { +                        while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\')) +                            ; +                        if (sc.GetRelative(i) == ']') +                            k = i; +                    } +                } +                // At least a link text +                if (j) { +                    sc.SetState(SCE_MARKDOWN_LINK); +                    sc.Forward(j); +                    // Also has a URL or reference portion +                    if (k) +                        sc.Forward(k - j); +                    sc.ForwardSetState(SCE_MARKDOWN_DEFAULT); +                } +            } +            // Code - also a special case for alternate inside spacing +            if (sc.Match("``") && sc.GetRelative(3) != ' ') { +                sc.SetState(SCE_MARKDOWN_CODE2); +                sc.Forward(); +            } +            else if (sc.ch == '`' && sc.chNext != ' ') { +                sc.SetState(SCE_MARKDOWN_CODE); +            } +            // Strong +            else if (sc.Match("**") && sc.GetRelative(2) != ' ') { +                sc.SetState(SCE_MARKDOWN_STRONG1); +                sc.Forward(); +           } +            else if (sc.Match("__") && sc.GetRelative(2) != ' ') { +                sc.SetState(SCE_MARKDOWN_STRONG2); +                sc.Forward(); +            } +            // Emphasis +            else if (sc.ch == '*' && sc.chNext != ' ') +                sc.SetState(SCE_MARKDOWN_EM1); +            else if (sc.ch == '_' && sc.chNext != ' ') +                sc.SetState(SCE_MARKDOWN_EM2); +            // Strikeout +            else if (sc.Match("~~") && sc.GetRelative(2) != ' ') { +                sc.SetState(SCE_MARKDOWN_STRIKEOUT); +                sc.Forward(); +            } +            // Beginning of line +            else if (IsNewline(sc.ch)) +                sc.SetState(SCE_MARKDOWN_LINE_BEGIN); +        } +        // Advance if not holding back the cursor for this iteration. +        if (!freezeCursor) +            sc.Forward(); +        freezeCursor = false; +    } +    sc.Complete(); +} + +LexerModule lmMarkdown(SCLEX_MARKDOWN, ColorizeMarkdownDoc, "markdown"); diff --git a/vcbuild/SciLexer.dsp b/vcbuild/SciLexer.dsp index bc4053b92..847989169 100644 --- a/vcbuild/SciLexer.dsp +++ b/vcbuild/SciLexer.dsp @@ -298,6 +298,10 @@ SOURCE=..\src\LexMagik.cxx  # End Source File  # Begin Source File +SOURCE=..\src\LexMarkdown.cxx +# End Source File +# Begin Source File +  SOURCE=..\src\LexMatlab.cxx  # End Source File  # Begin Source File diff --git a/win32/makefile b/win32/makefile index d2aa0d6cf..fc74dd22f 100644 --- a/win32/makefile +++ b/win32/makefile @@ -57,12 +57,13 @@ LexBaan.o LexBash.o LexBasic.o LexBullant.o LexCaml.o LexCLW.o LexCmake.o \  LexCOBOL.o LexConf.o LexCPP.o LexCrontab.o LexCsound.o LexCSS.o LexD.o \  LexEiffel.o LexErlang.o LexEScript.o LexFlagship.o LexForth.o LexFortran.o \  LexGAP.o LexGui4Cli.o LexHaskell.o LexHTML.o LexInno.o LexKix.o LexLisp.o \ -LexLout.o LexLua.o LexMagik.o LexMatlab.o LexMetapost.o LexMMIXAL.o LexMPT.o \ -LexMSSQL.o LexMySQL.o LexNimrod.o LexNsis.o LexOpal.o LexOthers.o LexPascal.o \ -LexPB.o LexPerl.o LexPLM.o LexPOV.o LexPowerPro.o LexPowerShell.o \ -LexProgress.o LexPS.o LexPython.o LexR.o LexRebol.o LexRuby.o LexScriptol.o \ -LexSmalltalk.o LexSML.o LexSorcus.o LexSpecman.o LexSpice.o LexSQL.o LexTACL.o \ -LexTADS3.o LexTAL.o LexTCL.o LexTeX.o LexVB.o LexVerilog.o LexVHDL.o LexYAML.o +LexLout.o LexLua.o LexMagik.o LexMarkdown.o LexMatlab.o LexMetapost.o \ +LexMMIXAL.o LexMPT.o LexMSSQL.o LexMySQL.o LexNimrod.o LexNsis.o LexOpal.o \ +LexOthers.o LexPascal.o LexPB.o LexPerl.o LexPLM.o LexPOV.o LexPowerPro.o \ +LexPowerShell.o LexProgress.o LexPS.o LexPython.o LexR.o LexRebol.o LexRuby.o \ +LexScriptol.o LexSmalltalk.o LexSML.o LexSorcus.o LexSpecman.o LexSpice.o \ +LexSQL.o LexTACL.o LexTADS3.o LexTAL.o LexTCL.o LexTeX.o LexVB.o LexVerilog.o \ +LexVHDL.o LexYAML.o  #--Autogenerated -- end of automatically generated section  SOBJS	= ScintillaWin.o ScintillaBase.o Editor.o CharClassify.o Decoration.o \ diff --git a/win32/scintilla.mak b/win32/scintilla.mak index f78c9f775..7c0c864b2 100644 --- a/win32/scintilla.mak +++ b/win32/scintilla.mak @@ -153,6 +153,7 @@ LEXOBJS=\  	$(DIR_O)\LexLout.obj \  	$(DIR_O)\LexLua.obj \  	$(DIR_O)\LexMagik.obj \ +	$(DIR_O)\LexMarkdown.obj \  	$(DIR_O)\LexMatlab.obj \  	$(DIR_O)\LexMetapost.obj \  	$(DIR_O)\LexMMIXAL.obj \ @@ -393,6 +394,8 @@ $(DIR_O)\LexLua.obj: ..\src\LexLua.cxx $(LEX_HEADERS)  $(DIR_O)\LexMagik.obj: ..\src\LexMagik.cxx $(LEX_HEADERS) +$(DIR_O)\LexMarkdown.obj: ..\src\LexMarkdown.cxx $(LEX_HEADERS) +  $(DIR_O)\LexMatlab.obj: ..\src\LexMatlab.cxx $(LEX_HEADERS)  $(DIR_O)\LexMetapost.obj: ..\src\LexMetapost.cxx $(LEX_HEADERS) diff --git a/win32/scintilla_vc6.mak b/win32/scintilla_vc6.mak index d160c38a0..c947422cf 100644 --- a/win32/scintilla_vc6.mak +++ b/win32/scintilla_vc6.mak @@ -155,6 +155,7 @@ LEXOBJS=\  	$(DIR_O)\LexLout.obj \  	$(DIR_O)\LexLua.obj \  	$(DIR_O)\LexMagik.obj \ +	$(DIR_O)\LexMarkdown.obj \  	$(DIR_O)\LexMatlab.obj \  	$(DIR_O)\LexMetapost.obj \  	$(DIR_O)\LexMMIXAL.obj \ @@ -395,6 +396,8 @@ $(DIR_O)\LexLua.obj: ..\src\LexLua.cxx $(LEX_HEADERS)  $(DIR_O)\LexMagik.obj: ..\src\LexMagik.cxx $(LEX_HEADERS) +$(DIR_O)\LexMarkdown.obj: ..\src\LexMarkdown.cxx $(LEX_HEADERS) +  $(DIR_O)\LexMatlab.obj: ..\src\LexMatlab.cxx $(LEX_HEADERS)  $(DIR_O)\LexMetapost.obj: ..\src\LexMetapost.cxx $(LEX_HEADERS) | 
