aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--doc/ScintillaHistory.html1
-rw-r--r--gtk/makefile13
-rw-r--r--gtk/scintilla.mak3
-rw-r--r--include/SciLexer.h23
-rw-r--r--include/Scintilla.iface25
-rw-r--r--macosx/makefile13
-rw-r--r--src/KeyWords.cxx1
-rw-r--r--src/LexMarkdown.cxx412
-rw-r--r--vcbuild/SciLexer.dsp4
-rw-r--r--win32/makefile13
-rw-r--r--win32/scintilla.mak3
-rw-r--r--win32/scintilla_vc6.mak3
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)