Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add Markdown filetype (patch by Jon Strait, thanks).

git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@4046 ea778897-0a13-0410-b9d1-a72fbfd435f5
  • Loading branch information...
commit 5e55af41fc044ba7ff3a33c5f690d963cc4a4eb9 1 parent 18bc1c2
@ntrel ntrel authored
View
7 ChangeLog
@@ -4,6 +4,13 @@
Rename 'Reflow lines/paragraph' to 'Reflow lines/block' because in
future using an indent block is more useful e.g. for ChangeLog
files.
+ * scintilla/LexMarkdown.cxx, scintilla/makefile.win32,
+ scintilla/include/SciLexer.h, scintilla/include/Scintilla.iface,
+ scintilla/KeyWords.cxx, scintilla/Makefile.am, src/highlighting.c,
+ src/about.c, src/filetypes.c, src/filetypes.h, THANKS,
+ tagmanager/parsers.h, tagmanager/makefile.win32,
+ tagmanager/markdown.c, tagmanager/Makefile.am, wscript:
+ Add Markdown filetype (patch by Jon Strait, thanks).
2009-07-29 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
View
1  THANKS
@@ -66,6 +66,7 @@ Simon Treny <simon(dot)treny(at)free(dot)fr> - Documents sidebar stock icons pat
Elias Pschernig <elias(at)users(dot)sourceforge(dot)net> - Recent Projects menu patch
Jesse Mayes <plasmasheep(at)gmail(dot)com> - Tango'ish Save All icon
Eugene Arshinov <earshinov(at)gmail(dot)com> - Reload color schemes, split lines KB patches
+Jon Strait <jstrait(at)moonloop(dot)net> - Markdown filetype patch
Translators:
------------
View
1  scintilla/KeyWords.cxx
@@ -158,6 +158,7 @@ int Scintilla_LinkLexers() {
LINK_LEXER(lmLatex);
LINK_LEXER(lmLua);
LINK_LEXER(lmMake);
+ LINK_LEXER(lmMarkdown);
LINK_LEXER(lmMatlab);
LINK_LEXER(lmNsis);
LINK_LEXER(lmNull);
View
433 scintilla/LexMarkdown.cxx
@@ -0,0 +1,433 @@
+/******************************************************************
+ * 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; something Scintilla isn't really architected
+ * to support yet.
+ *
+ * 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
+ *
+ * This source code is released for free distribution under the
+ * terms of the GNU General Public License.
+ *
+ *****************************************************************/
+
+#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 int endPos, StyleContext &sc) {
+ 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) {
+ int i = 0;
+ sc.SetState(state);
+ sc.Forward(length);
+ sc.SetState(SCE_MARKDOWN_DEFAULT);
+ sc.Forward();
+ while (sc.More() && !IsNewline(sc.ch)) {
+ bool started = false;
+ 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 int endPos, StyleContext &sc) {
+ int c, i = 0, count = 1;
+ 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;
+ }
+ }
+ }
+}
+
+// Only consume if already valid. Doesn't work for delimiting multiple lines.
+static void ConsumeEnd(const int state, const int origPos, const int endPos,
+ const char *token, StyleContext &sc) {
+ int targetPos;
+ while (sc.currentPos + 1 < endPos) {
+ sc.Forward();
+ if (sc.Match(token) && sc.chPrev != '\\' && sc.chPrev != ' ') {
+ targetPos = sc.currentPos + strlen(token);
+ sc.currentPos = origPos;
+ sc.SetState(state);
+ sc.Forward(targetPos - origPos);
+ sc.SetState(SCE_MARKDOWN_DEFAULT);
+ break;
+ }
+ }
+}
+
+static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+
+ int digitCount = 0;
+ int endPos = startPos + length;
+ int precharCount;
+ // 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)) {
+ 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) {
+ int origPos = sc.currentPos;
+ 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");
+
View
7 scintilla/Makefile.am
@@ -19,10 +19,10 @@ LexD.cxx \
LexFortran.cxx \
LexHaskell.cxx \
LexHTML.cxx \
-LexYAML.cxx \
LexLua.cxx \
-LexNsis.cxx \
+LexMarkdown.cxx \
LexMatlab.cxx \
+LexNsis.cxx \
LexOthers.cxx \
LexPascal.cxx \
LexPerl.cxx \
@@ -31,7 +31,8 @@ LexR.cxx \
LexRuby.cxx \
LexSQL.cxx \
LexTCL.cxx \
-LexVHDL.cxx
+LexVHDL.cxx \
+LexYAML.cxx
SRCS= \
CallTip.cxx \
View
23 scintilla/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
@@ -1277,6 +1278,28 @@
#define SCE_MYSQL_USER2 19
#define SCE_MYSQL_USER3 20
#define SCE_MYSQL_HIDDENCOMMAND 21
+#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
#define SCE_PO_DEFAULT 0
#define SCE_PO_COMMENT 1
#define SCE_PO_MSGID 2
View
25 scintilla/include/Scintilla.iface
@@ -2135,6 +2135,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.
@@ -3545,6 +3546,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
View
3  scintilla/makefile.win32
@@ -61,7 +61,8 @@ MARSHALLER=scintilla-marshal.o
#**LEXOBJS=\\\n\(\*.o \)
LEXOBJS=\
LexAda.o LexBash.o LexAsm.o LexCSS.o LexCPP.o LexCrontab.o LexHTML.o LexOthers.o LexPascal.o \
-LexPerl.o LexPython.o LexSQL.o LexCaml.o LexTCL.o LexRuby.o LexFortran.o LexVHDL.o LexMatlab.o \
+LexPerl.o LexPython.o LexSQL.o LexCaml.o LexTCL.o LexRuby.o LexFortran.o LexVHDL.o \
+LexMarkdown.o LexMatlab.o \
LexD.o LexLua.o LexHaskell.o LexBasic.o LexR.o LexYAML.o LexCmake.o LexNsis.o
#--Autogenerated -- end of automatically generated section
View
2  src/about.c
@@ -84,7 +84,7 @@ static const gchar *contributors =
"Chris Macksey, Christoph Berg, Colomban Wendling, Conrad Steenberg, Daniel Richard G., Dave Moore, Dirk Weber, "
"Elias Pschernig, Eugene Arshinov, Felipe Pena, François Cami, "
"Giuseppe Torelli, Guillaume de Rorthais, Guillaume Hoffmann, Herbert Voss, Jason Oster, Jean-François Wauthy, Jeff Pohlmeyer, "
-"Jesse Mayes, John Gabriele, Josef Whiter, Kevin Ellwood, Kristoffer A. Tjernås, Marko Peric, Matti Mårds, Moritz Barsnick, "
+"Jesse Mayes, John Gabriele, Jon Strait, Josef Whiter, Kevin Ellwood, Kristoffer A. Tjernås, Marko Peric, Matti Mårds, Moritz Barsnick, "
"Peter Strand, Philipp Gildein, Pierre Joye, Rob van der Linde, Robert McGinley, Roland Baudin, S Jagannathan, Saleem Abdulrasool, "
"Sebastian Kraft, Shiv, Slava Semushin, Stefan Oltmanns, Tamim, Thomas Martitz, Tomás Vírseda, "
"Tyler Mulligan, Walery Studennikov, Yura Siamashka";
View
11 src/filetypes.c
@@ -341,6 +341,17 @@ static void init_builtin_filetypes(void)
ft->comment_close = NULL;
ft->group = GEANY_FILETYPE_GROUP_COMPILED;
+#define MARKDOWN
+ ft = filetypes[GEANY_FILETYPES_MARKDOWN];
+ ft->lang = 36;
+ ft->name = g_strdup("Markdown");
+ ft->title = g_strdup_printf(_("%s source file"), "Markdown");
+ ft->extension = g_strdup("md");
+ ft->pattern = utils_strv_new("*.mdml", "*.mdwn", "*.markdown", "*.md", NULL);
+ ft->comment_open = NULL;
+ ft->comment_close = NULL;
+ ft->group = GEANY_FILETYPE_GROUP_MISC;
+
#define SH
ft = filetypes[GEANY_FILETYPES_SH];
ft->lang = 16;
View
2  src/filetypes.h
@@ -76,7 +76,7 @@ typedef enum
GEANY_FILETYPES_VHDL,
GEANY_FILETYPES_ADA,
GEANY_FILETYPES_CMAKE,
-
+ GEANY_FILETYPES_MARKDOWN,
/* ^ append items here */
GEANY_MAX_BUILT_IN_FILETYPES /* Don't use this, use filetypes_array->len instead */
}
View
60 src/highlighting.c
@@ -2725,6 +2725,64 @@ static void styleset_sql(ScintillaObject *sci)
}
+static void styleset_markdown_init(gint ft_id, GKeyFile *config, GKeyFile *config_home)
+{
+ new_style_array(GEANY_FILETYPES_MARKDOWN, 17);
+
+ get_keyfile_hex(config, config_home, "default", 0x000000, 0xffffff, FALSE, &style_sets[GEANY_FILETYPES_MARKDOWN].styling[0]);
+ get_keyfile_hex(config, config_home, "strong", 0xff0000, 0xffffff, FALSE, &style_sets[GEANY_FILETYPES_MARKDOWN].styling[1]);
+ get_keyfile_hex(config, config_home, "emphasis", 0xff0000, 0xffffff, FALSE, &style_sets[GEANY_FILETYPES_MARKDOWN].styling[2]);
+ get_keyfile_hex(config, config_home, "header1", 0x0000bb, 0xffffff, FALSE, &style_sets[GEANY_FILETYPES_MARKDOWN].styling[3]);
+ get_keyfile_hex(config, config_home, "header2", 0x0000bb, 0xffffff, FALSE, &style_sets[GEANY_FILETYPES_MARKDOWN].styling[4]);
+ get_keyfile_hex(config, config_home, "header3", 0x0000bb, 0xffffff, FALSE, &style_sets[GEANY_FILETYPES_MARKDOWN].styling[5]);
+ get_keyfile_hex(config, config_home, "header4", 0x0000bb, 0xffffff, FALSE, &style_sets[GEANY_FILETYPES_MARKDOWN].styling[6]);
+ get_keyfile_hex(config, config_home, "header5", 0x0000bb, 0xffffff, FALSE, &style_sets[GEANY_FILETYPES_MARKDOWN].styling[7]);
+ get_keyfile_hex(config, config_home, "header6", 0x0000bb, 0xffffff, FALSE, &style_sets[GEANY_FILETYPES_MARKDOWN].styling[8]);
+ get_keyfile_hex(config, config_home, "ulist_item", 0x007f00, 0xffffff, FALSE, &style_sets[GEANY_FILETYPES_MARKDOWN].styling[9]);
+ get_keyfile_hex(config, config_home, "olist_item", 0x007f00, 0xffffff, FALSE, &style_sets[GEANY_FILETYPES_MARKDOWN].styling[10]);
+ get_keyfile_hex(config, config_home, "blockquote", 0xff0000, 0xffffff, FALSE, &style_sets[GEANY_FILETYPES_MARKDOWN].styling[11]);
+ get_keyfile_hex(config, config_home, "strikeout", 0xaa00ff, 0xffffff, FALSE, &style_sets[GEANY_FILETYPES_MARKDOWN].styling[12]);
+ get_keyfile_hex(config, config_home, "hrule", 0xff901e, 0xffffff, FALSE, &style_sets[GEANY_FILETYPES_MARKDOWN].styling[13]);
+ get_keyfile_hex(config, config_home, "link", 0x0000ff, 0xffffff, FALSE, &style_sets[GEANY_FILETYPES_MARKDOWN].styling[14]);
+ get_keyfile_hex(config, config_home, "code", 0x009f00, 0xffffff, FALSE, &style_sets[GEANY_FILETYPES_MARKDOWN].styling[15]);
+ get_keyfile_hex(config, config_home, "codebk", 0x005f00, 0xffffff, FALSE, &style_sets[GEANY_FILETYPES_MARKDOWN].styling[16]);
+
+ style_sets[GEANY_FILETYPES_MARKDOWN].keywords = NULL;
+
+ get_keyfile_wordchars(config, config_home, &style_sets[GEANY_FILETYPES_MARKDOWN].wordchars);
+}
+
+static void styleset_markdown(ScintillaObject *sci)
+{
+ const filetype_id ft_id = GEANY_FILETYPES_MARKDOWN;
+
+ apply_filetype_properties(sci, SCLEX_MARKDOWN, ft_id);
+
+ set_sci_style(sci, STYLE_DEFAULT, GEANY_FILETYPES_MARKDOWN, 0);
+ set_sci_style(sci, SCE_MARKDOWN_DEFAULT, GEANY_FILETYPES_MARKDOWN, 0);
+ set_sci_style(sci, SCE_MARKDOWN_LINE_BEGIN, GEANY_FILETYPES_MARKDOWN, 0);
+ set_sci_style(sci, SCE_MARKDOWN_PRECHAR, GEANY_FILETYPES_MARKDOWN, 0);
+ set_sci_style(sci, SCE_MARKDOWN_STRONG1, GEANY_FILETYPES_MARKDOWN, 1);
+ set_sci_style(sci, SCE_MARKDOWN_STRONG2, GEANY_FILETYPES_MARKDOWN, 1);
+ set_sci_style(sci, SCE_MARKDOWN_EM1, GEANY_FILETYPES_MARKDOWN, 2);
+ set_sci_style(sci, SCE_MARKDOWN_EM2, GEANY_FILETYPES_MARKDOWN, 2);
+ set_sci_style(sci, SCE_MARKDOWN_HEADER1, GEANY_FILETYPES_MARKDOWN, 3);
+ set_sci_style(sci, SCE_MARKDOWN_HEADER2, GEANY_FILETYPES_MARKDOWN, 4);
+ set_sci_style(sci, SCE_MARKDOWN_HEADER3, GEANY_FILETYPES_MARKDOWN, 5);
+ set_sci_style(sci, SCE_MARKDOWN_HEADER4, GEANY_FILETYPES_MARKDOWN, 6);
+ set_sci_style(sci, SCE_MARKDOWN_HEADER5, GEANY_FILETYPES_MARKDOWN, 7);
+ set_sci_style(sci, SCE_MARKDOWN_HEADER6, GEANY_FILETYPES_MARKDOWN, 8);
+ set_sci_style(sci, SCE_MARKDOWN_ULIST_ITEM, GEANY_FILETYPES_MARKDOWN, 9);
+ set_sci_style(sci, SCE_MARKDOWN_OLIST_ITEM, GEANY_FILETYPES_MARKDOWN, 10);
+ set_sci_style(sci, SCE_MARKDOWN_BLOCKQUOTE, GEANY_FILETYPES_MARKDOWN, 11);
+ set_sci_style(sci, SCE_MARKDOWN_STRIKEOUT, GEANY_FILETYPES_MARKDOWN, 12);
+ set_sci_style(sci, SCE_MARKDOWN_HRULE, GEANY_FILETYPES_MARKDOWN, 13);
+ set_sci_style(sci, SCE_MARKDOWN_LINK, GEANY_FILETYPES_MARKDOWN, 14);
+ set_sci_style(sci, SCE_MARKDOWN_CODE, GEANY_FILETYPES_MARKDOWN, 15);
+ set_sci_style(sci, SCE_MARKDOWN_CODE2, GEANY_FILETYPES_MARKDOWN, 15);
+ set_sci_style(sci, SCE_MARKDOWN_CODEBK, GEANY_FILETYPES_MARKDOWN, 16);
+}
+
static void styleset_haskell_init(gint ft_id, GKeyFile *config, GKeyFile *config_home)
{
new_style_array(GEANY_FILETYPES_HASKELL, 17);
@@ -3599,6 +3657,7 @@ void highlighting_init_styles(gint filetype_idx, GKeyFile *config, GKeyFile *con
init_styleset_case(GEANY_FILETYPES_LUA, styleset_lua_init);
init_styleset_case(GEANY_FILETYPES_MAKE, styleset_makefile_init);
init_styleset_case(GEANY_FILETYPES_MATLAB, styleset_matlab_init);
+ init_styleset_case(GEANY_FILETYPES_MARKDOWN, styleset_markdown_init);
init_styleset_case(GEANY_FILETYPES_NSIS, styleset_nsis_init);
init_styleset_case(GEANY_FILETYPES_PASCAL, styleset_pascal_init);
init_styleset_case(GEANY_FILETYPES_PERL, styleset_perl_init);
@@ -3660,6 +3719,7 @@ void highlighting_set_styles(ScintillaObject *sci, gint filetype_idx)
styleset_case(GEANY_FILETYPES_LATEX, styleset_latex);
styleset_case(GEANY_FILETYPES_LUA, styleset_lua);
styleset_case(GEANY_FILETYPES_MAKE, styleset_makefile);
+ styleset_case(GEANY_FILETYPES_MARKDOWN, styleset_markdown);
styleset_case(GEANY_FILETYPES_MATLAB, styleset_matlab);
styleset_case(GEANY_FILETYPES_NSIS, styleset_nsis);
styleset_case(GEANY_FILETYPES_PASCAL, styleset_pascal);
View
1  tagmanager/Makefile.am
@@ -51,6 +51,7 @@ libtagmanager_a_SOURCES =\
latex.c\
lregex.c\
matlab.c\
+ markdown.c\
pascal.c\
perl.c\
rest.c\
View
2  tagmanager/makefile.win32
@@ -43,7 +43,7 @@ $(COMPLIB): args.o c.o fortran.o make.o conf.o pascal.o perl.o php.o diff.o vhdl
actionscript.o nsis.o \
haskell.o haxe.o html.o python.o lregex.o rest.o sh.o ctags.o entry.o get.o keyword.o nestlevel.o \
options.o \
-parse.o basic.o read.o sort.o strlist.o latex.o matlab.o docbook.o tcl.o ruby.o asm.o sql.o css.o \
+parse.o basic.o read.o sort.o strlist.o latex.o markdown.o matlab.o docbook.o tcl.o ruby.o asm.o sql.o css.o \
vstring.o regex.o tm_workspace.o tm_work_object.o tm_source_file.o tm_project.o tm_tag.o \
tm_symbol.o tm_file_entry.o tm_tagmanager.o
$(AR) rc $@ $^
View
105 tagmanager/markdown.c
@@ -0,0 +1,105 @@
+/*
+*
+* Copyright (c) 2009, Jon Strait
+*
+* This source code is released for free distribution under the terms of the
+* GNU General Public License.
+*
+* This module contains functions for generating tags for Markdown files.
+*/
+
+/*
+* INCLUDE FILES
+*/
+#include "general.h" /* must always come first */
+
+#include <ctype.h>
+#include <string.h>
+
+#include "parse.h"
+#include "read.h"
+#include "vstring.h"
+
+/*
+* DATA DEFINITIONS
+*/
+
+static kindOption MarkdownKinds[] = {
+ { TRUE, 'v', "variable", "sections" }
+};
+
+/*
+* FUNCTION DEFINITIONS
+*/
+
+/* checks if str is all the same character */
+static boolean issame(const char *str)
+{
+ char first = *str;
+
+ while (*(++str))
+ {
+ if (*str && *str != first)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void makeMarkdownTag (const vString* const name, boolean name_before)
+{
+ tagEntryInfo e;
+ initTagEntry (&e, vStringValue(name));
+
+ if (name_before)
+ e.lineNumber--; /* we want the line before the underline chars */
+ e.kindName = "variable";
+ e.kind = 'v';
+
+ makeTagEntry(&e);
+}
+
+
+static void findMarkdownTags (void)
+{
+ vString *name = vStringNew();
+ const unsigned char *line;
+
+ while ((line = fileReadLine()) != NULL)
+ {
+ int name_len = vStringLength(name);
+
+ /* underlines must be the same length or more */
+ if (name_len > 0 && (line[0] == '=' || line[0] == '-') && issame((const char*) line))
+ {
+ makeMarkdownTag(name, TRUE);
+ }
+ else if (line[0] == '#') {
+ vStringClear(name);
+ vStringCatS(name, (const char *) line);
+ vStringTerminate(name);
+ makeMarkdownTag(name, FALSE);
+ }
+ else {
+ vStringClear (name);
+ if (! isspace(*line))
+ vStringCatS(name, (const char*) line);
+ vStringTerminate(name);
+ }
+ }
+ vStringDelete (name);
+}
+
+extern parserDefinition* MarkdownParser (void)
+{
+ static const char *const patterns [] = { "*.md", NULL };
+ static const char *const extensions [] = { "md", NULL };
+ parserDefinition* const def = parserNew ("Markdown");
+
+ def->kinds = MarkdownKinds;
+ def->kindCount = KIND_COUNT (MarkdownKinds);
+ def->patterns = patterns;
+ def->extensions = extensions;
+ def->parser = findMarkdownTags;
+ return def;
+}
+
View
5 tagmanager/parsers.h
@@ -50,8 +50,8 @@
MatlabParser, \
ValaParser, \
ActionScriptParser, \
- NsisParser
-
+ NsisParser, \
+ MarkdownParser
/*
langType of each parser
0 CParser
@@ -90,6 +90,7 @@ langType of each parser
33 ValaParser
34 ActionScriptParser
35 NsisParser
+36 MarkdownParser
*/
#endif /* _PARSERS_H */
View
13 wscript
@@ -58,7 +58,7 @@ tagmanager_sources = [
'tagmanager/docbook.c', 'tagmanager/entry.c', 'tagmanager/fortran.c', 'tagmanager/get.c',
'tagmanager/haskell.c', 'tagmanager/haxe.c', 'tagmanager/html.c', 'tagmanager/js.c',
'tagmanager/keyword.c', 'tagmanager/latex.c', 'tagmanager/lregex.c', 'tagmanager/lua.c',
- 'tagmanager/make.c', 'tagmanager/matlab.c', 'tagmanager/nsis.c',
+ 'tagmanager/make.c', 'tagmanager/markdown.c', 'tagmanager/matlab.c', 'tagmanager/nsis.c',
'tagmanager/nestlevel.c', 'tagmanager/options.c',
'tagmanager/parse.c', 'tagmanager/pascal.c',
'tagmanager/perl.c', 'tagmanager/php.c', 'tagmanager/python.c', 'tagmanager/read.c',
@@ -73,15 +73,18 @@ scintilla_sources = [
'scintilla/CharClassify.cxx', 'scintilla/ContractionState.cxx', 'scintilla/Decoration.cxx',
'scintilla/DocumentAccessor.cxx', 'scintilla/Document.cxx', 'scintilla/Editor.cxx',
'scintilla/ExternalLexer.cxx', 'scintilla/Indicator.cxx', 'scintilla/KeyMap.cxx',
- 'scintilla/KeyWords.cxx', 'scintilla/LexAda.cxx', 'scintilla/LexAsm.cxx', 'scintilla/LexBash.cxx',
+ 'scintilla/KeyWords.cxx',
+ 'scintilla/LexAda.cxx', 'scintilla/LexAsm.cxx', 'scintilla/LexBash.cxx',
'scintilla/LexBasic.cxx', 'scintilla/LexCaml.cxx', 'scintilla/LexCmake.cxx', 'scintilla/LexCPP.cxx',
'scintilla/LexCrontab.cxx', 'scintilla/LexCSS.cxx', 'scintilla/LexD.cxx',
'scintilla/LexFortran.cxx', 'scintilla/LexHaskell.cxx', 'scintilla/LexHTML.cxx',
- 'scintilla/LexLua.cxx', 'scintilla/LexNsis.cxx', 'scintilla/LexOthers.cxx',
+ 'scintilla/LexLua.cxx', 'scintilla/LexMarkdown.cxx', 'scintilla/LexMatlab.cxx',
+ 'scintilla/LexNsis.cxx', 'scintilla/LexOthers.cxx',
'scintilla/LexPascal.cxx', 'scintilla/LexPerl.cxx', 'scintilla/LexPython.cxx',
- 'scintilla/LexR.cxx', 'scintilla/LexMatlab.cxx', 'scintilla/LexYAML.cxx',
+ 'scintilla/LexR.cxx',
'scintilla/LexRuby.cxx', 'scintilla/LexSQL.cxx', 'scintilla/LexTCL.cxx',
- 'scintilla/LexVHDL.cxx', 'scintilla/LineMarker.cxx', 'scintilla/PerLine.cxx',
+ 'scintilla/LexVHDL.cxx', 'scintilla/LexYAML.cxx',
+ 'scintilla/LineMarker.cxx', 'scintilla/PerLine.cxx',
'scintilla/PlatGTK.cxx',
'scintilla/PositionCache.cxx', 'scintilla/PropSet.cxx', 'scintilla/RESearch.cxx',
'scintilla/RunStyles.cxx', 'scintilla/ScintillaBase.cxx', 'scintilla/ScintillaGTK.cxx',
Please sign in to comment.
Something went wrong with that request. Please try again.