improved markdown mode
* made language support for code blocks generic * fixed HTML comments * fixed state bit allocation * improved HTML block support with fewer state collisions * colorize text and code in block quotes
This commit is contained in:
parent
2d82194349
commit
78f3b2ec0c
1 changed files with 84 additions and 83 deletions
167
markdown.c
167
markdown.c
|
|
@ -43,21 +43,32 @@ enum {
|
|||
};
|
||||
|
||||
enum {
|
||||
IN_MKD_HTML_BLOCK = 0x8000,
|
||||
IN_MKD_BLOCK = 0x4000,
|
||||
IN_MKD_LANG = 0x3800,
|
||||
IN_MKD_C = 0x0800,
|
||||
IN_MKD_JAVA = 0x1000,
|
||||
IN_MKD_PYTHON = 0x1800,
|
||||
IN_MKD_RUBY = 0x2000,
|
||||
IN_MKD_HASKELL = 0x2800,
|
||||
IN_MKD_LUA = 0x3000,
|
||||
IN_MKD_SWIFT = 0x3800,
|
||||
IN_MKD_LEVEL = 0x0700,
|
||||
IN_MKD_LANG_STATE = 0x00FF,
|
||||
IN_MKD_LEVEL = 0x0700,
|
||||
IN_MKD_BLOCK = 0x7800,
|
||||
IN_MKD_HTML_BLOCK = 0x8000,
|
||||
IN_MKD_HTML_COMMENT = 0xC000,
|
||||
MKD_LANG_SHIFT = 11,
|
||||
MKD_LANG_MAX = 16,
|
||||
MKD_LEVEL_SHIFT = 8,
|
||||
MKD_LEVEL_MAX = 7,
|
||||
};
|
||||
|
||||
#define MKD_LEVEL_SHIFT 8
|
||||
#define MKD_MAX_LEVEL 128
|
||||
ModeDef *mkd_lang_def[MKD_LANG_MAX - 1] = {
|
||||
NULL,
|
||||
&js_mode,
|
||||
&java_mode,
|
||||
&scala_mode,
|
||||
&php_mode,
|
||||
&csharp_mode,
|
||||
&python_mode,
|
||||
&ruby_mode,
|
||||
&haskell_mode,
|
||||
&lua_mode,
|
||||
&swift_mode,
|
||||
&cpp_mode,
|
||||
&c_mode,
|
||||
};
|
||||
|
||||
#define MKD_BULLET_STYLES 4
|
||||
static int MkdBulletStyles[MKD_BULLET_STYLES] = {
|
||||
|
|
@ -97,9 +108,30 @@ static void mkd_colorize_line(QEColorizeContext *cp,
|
|||
int colstate = cp->colorize_state;
|
||||
int level, indent, i = 0, j, start = i, base_style = 0;
|
||||
|
||||
if (str[i] == '<' && str[i + 1] == '!' && str[i + 2] == '-' && str[i + 3] == '-') {
|
||||
colstate |= IN_MKD_HTML_COMMENT;
|
||||
i += 3;
|
||||
}
|
||||
|
||||
if ((colstate & IN_MKD_HTML_COMMENT) == IN_MKD_HTML_COMMENT) {
|
||||
while (i < n) {
|
||||
int c = str[i++];
|
||||
if (c == '-' && str[i] == '-' && str[i + 1] == '>') {
|
||||
i += 2;
|
||||
colstate &= ~IN_MKD_HTML_COMMENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SET_COLOR(str, start, i, MKD_STYLE_COMMENT);
|
||||
cp->colorize_state = colstate;
|
||||
return;
|
||||
}
|
||||
|
||||
if (colstate & IN_MKD_HTML_BLOCK) {
|
||||
if (str[i] != '<' && str[i] != '\0' && !qe_isblank(str[i]))
|
||||
colstate &= ~IN_MKD_HTML_BLOCK;
|
||||
if (str[i] != '<' && str[i] != '\0' && !qe_isblank(str[i])) {
|
||||
/* formating error, exit html block */
|
||||
colstate = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((colstate & IN_MKD_HTML_BLOCK)
|
||||
|
|
@ -116,48 +148,33 @@ static void mkd_colorize_line(QEColorizeContext *cp,
|
|||
return;
|
||||
}
|
||||
|
||||
if (str[i] == '>') {
|
||||
if (str[++i] == ' ')
|
||||
i++;
|
||||
SET_COLOR(str, start, i, MKD_STYLE_BLOCK_QUOTE);
|
||||
start = i;
|
||||
}
|
||||
|
||||
if (colstate & IN_MKD_BLOCK) {
|
||||
/* Should count number of ~ to detect end of block */
|
||||
if (ustrstart(str + i, "~~~", NULL)
|
||||
|| ustrstart(str + i, "```", NULL)) {
|
||||
colstate &= ~(IN_MKD_BLOCK | IN_MKD_LANG);
|
||||
colstate &= ~IN_MKD_BLOCK;
|
||||
i = n;
|
||||
SET_COLOR(str, start, i, MKD_STYLE_TILDE);
|
||||
} else {
|
||||
int lang = colstate & IN_MKD_LANG;
|
||||
int lang = (colstate & IN_MKD_BLOCK) >> MKD_LANG_SHIFT;
|
||||
|
||||
colstate &= ~(IN_MKD_BLOCK | IN_MKD_LANG);
|
||||
cp->colorize_state = colstate;
|
||||
cp->colorize_state = colstate & IN_MKD_LANG_STATE;
|
||||
|
||||
switch (lang) {
|
||||
case IN_MKD_C:
|
||||
c_mode.colorize_func(cp, str, n, &c_mode);
|
||||
break;
|
||||
case IN_MKD_JAVA:
|
||||
java_mode.colorize_func(cp, str, n, &java_mode);
|
||||
break;
|
||||
case IN_MKD_PYTHON:
|
||||
python_mode.colorize_func(cp, str, n, &python_mode);
|
||||
break;
|
||||
case IN_MKD_RUBY:
|
||||
ruby_mode.colorize_func(cp, str, n, &ruby_mode);
|
||||
break;
|
||||
case IN_MKD_HASKELL:
|
||||
haskell_mode.colorize_func(cp, str, n, &haskell_mode);
|
||||
break;
|
||||
case IN_MKD_LUA:
|
||||
lua_mode.colorize_func(cp, str, n, &lua_mode);
|
||||
break;
|
||||
case IN_MKD_SWIFT:
|
||||
swift_mode.colorize_func(cp, str, n, &swift_mode);
|
||||
break;
|
||||
default:
|
||||
if (lang < countof(mkd_lang_def) && mkd_lang_def[lang]) {
|
||||
mkd_lang_def[lang]->colorize_func(cp, str + i, n - i, mkd_lang_def[lang]);
|
||||
} else {
|
||||
SET_COLOR(str, i, n, MKD_STYLE_CODE);
|
||||
break;
|
||||
}
|
||||
colstate = cp->colorize_state;
|
||||
colstate &= ~(IN_MKD_BLOCK | IN_MKD_LANG);
|
||||
colstate |= (IN_MKD_BLOCK | lang);
|
||||
i = n;
|
||||
colstate &= ~IN_MKD_LANG_STATE;
|
||||
colstate |= cp->colorize_state & IN_MKD_LANG_STATE;
|
||||
}
|
||||
cp->colorize_state = colstate;
|
||||
return;
|
||||
|
|
@ -179,39 +196,6 @@ static void mkd_colorize_line(QEColorizeContext *cp,
|
|||
i = n;
|
||||
SET_COLOR(str, start, i, MKD_STYLE_COMMENT);
|
||||
} else
|
||||
if (str[i] == '>') {
|
||||
/* block quoting */
|
||||
i = n;
|
||||
SET_COLOR(str, start, i, MKD_STYLE_BLOCK_QUOTE);
|
||||
} else
|
||||
if (ustrstart(str + i, "~~~", NULL)
|
||||
|| ustrstart(str + i, "```", NULL)) {
|
||||
/* verbatim block */
|
||||
colstate |= IN_MKD_BLOCK;
|
||||
if (ustrstr(str + i + 3, "c")) {
|
||||
colstate |= IN_MKD_C;
|
||||
} else
|
||||
if (ustrstr(str + i + 3, "java")) {
|
||||
colstate |= IN_MKD_JAVA;
|
||||
} else
|
||||
if (ustrstr(str + i + 3, "haskell")) {
|
||||
colstate |= IN_MKD_HASKELL;
|
||||
} else
|
||||
if (ustrstr(str + i + 3, "lua")) {
|
||||
colstate |= IN_MKD_LUA;
|
||||
} else
|
||||
if (ustrstr(str + i + 3, "python")) {
|
||||
colstate |= IN_MKD_PYTHON;
|
||||
} else
|
||||
if (ustrstr(str + i + 3, "ruby")) {
|
||||
colstate |= IN_MKD_RUBY;
|
||||
} else
|
||||
if (ustrstr(str + i + 3, "swift")) {
|
||||
colstate |= IN_MKD_SWIFT;
|
||||
}
|
||||
i = n;
|
||||
SET_COLOR(str, start, i, MKD_STYLE_TILDE);
|
||||
} else
|
||||
if (str[i] == '-') {
|
||||
/* dashes underline a heading */
|
||||
for (i++; str[i] == '-'; i++)
|
||||
|
|
@ -230,6 +214,23 @@ static void mkd_colorize_line(QEColorizeContext *cp,
|
|||
} else
|
||||
if (str[i] == '|') {
|
||||
base_style = MKD_STYLE_TABLE;
|
||||
} else
|
||||
if (ustrstart(str + i, "~~~", NULL)
|
||||
|| ustrstart(str + i, "```", NULL)) {
|
||||
/* verbatim block */
|
||||
int lang;
|
||||
|
||||
colstate &= ~(IN_MKD_BLOCK | IN_MKD_LANG_STATE);
|
||||
for (j = i + 3; qe_isspace(str[j]); j++)
|
||||
continue;
|
||||
for (lang = 1; lang < countof(mkd_lang_def); lang++) {
|
||||
if (mkd_lang_def[lang]
|
||||
&& ustristart(str + j, mkd_lang_def[lang]->name, NULL))
|
||||
break;
|
||||
}
|
||||
colstate |= lang << MKD_LANG_SHIFT;
|
||||
i = n;
|
||||
SET_COLOR(str, start, i, MKD_STYLE_TILDE);
|
||||
}
|
||||
|
||||
/* [X] unordered lists: /[-*+] / */
|
||||
|
|
@ -489,12 +490,12 @@ static int mkd_prev_heading(EditState *s, int offset, int target, int *level)
|
|||
|
||||
static void do_outline_next_vsible_heading(EditState *s)
|
||||
{
|
||||
s->offset = mkd_next_heading(s, s->offset, MKD_MAX_LEVEL, NULL);
|
||||
s->offset = mkd_next_heading(s, s->offset, MKD_LEVEL_MAX, NULL);
|
||||
}
|
||||
|
||||
static void do_outline_previous_vsible_heading(EditState *s)
|
||||
{
|
||||
s->offset = mkd_prev_heading(s, s->offset, MKD_MAX_LEVEL, NULL);
|
||||
s->offset = mkd_prev_heading(s, s->offset, MKD_LEVEL_MAX, NULL);
|
||||
}
|
||||
|
||||
static void do_outline_up_heading(EditState *s)
|
||||
|
|
@ -581,7 +582,7 @@ static void do_mkd_mark_element(EditState *s, int subtree)
|
|||
if (offset < 0)
|
||||
return;
|
||||
|
||||
offset1 = mkd_next_heading(s, offset, subtree ? level : MKD_MAX_LEVEL, NULL);
|
||||
offset1 = mkd_next_heading(s, offset, subtree ? level : MKD_LEVEL_MAX, NULL);
|
||||
|
||||
/* XXX: if repeating last command, add subtree to region */
|
||||
if (qs->last_cmd_func != qs->this_cmd_func)
|
||||
|
|
@ -680,7 +681,7 @@ static void do_mkd_promote_subtree(EditState *s, int dir)
|
|||
return;
|
||||
}
|
||||
}
|
||||
offset = mkd_next_heading(s, offset, MKD_MAX_LEVEL, &level1);
|
||||
offset = mkd_next_heading(s, offset, MKD_LEVEL_MAX, &level1);
|
||||
if (level1 <= level)
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue