From d210957cd8f48768e2993f2cc1cf9ba4f6a6afac Mon Sep 17 00:00:00 2001 From: Demi Obenour Date: Fri, 14 Jul 2017 18:51:10 -0400 Subject: [PATCH 01/17] Add mostly-complete support for Reddit-style autolinks Links of form u/a are still broken (leading '/' in href is missing). --- md2html/md2html.c | 7 +++++++ md2html/render_html.c | 2 +- md4c/md4c.c | 24 ++++++++++++++++++++++++ md4c/md4c.h | 2 ++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/md2html/md2html.c b/md2html/md2html.c index f9a5548a..02f84c3f 100644 --- a/md2html/md2html.c +++ b/md2html/md2html.c @@ -195,6 +195,7 @@ static const option cmdline_options[] = { { "version", 'v', 'v', OPTION_ARG_NONE }, { "commonmark", 0, 'c', OPTION_ARG_NONE }, { "github", 0, 'g', OPTION_ARG_NONE }, + { "reddit", 0, 'R', OPTION_ARG_NONE }, { "fverbatim-entities", 0, 'E', OPTION_ARG_NONE }, { "fpermissive-atx-headers", 0, 'A', OPTION_ARG_NONE }, { "fpermissive-url-autolinks", 0, 'U', OPTION_ARG_NONE }, @@ -208,6 +209,7 @@ static const option cmdline_options[] = { { "fcollapse-whitespace", 0, 'W', OPTION_ARG_NONE }, { "ftables", 0, 'T', OPTION_ARG_NONE }, { "fstrikethrough", 0, 'S', OPTION_ARG_NONE }, + { "freddit-autolinks", 0, 'r', OPTION_ARG_NONE }, { 0 } }; @@ -229,6 +231,7 @@ usage(void) "(note these are equivalent to some combinations of flags below)\n" " --commonmark CommonMark (this is default)\n" " --github Github Flavored Markdown\n" + " --reddit Reddit's dialect of Markdown\n" "\n" "Markdown extension options:\n" " --fcollapse-whitespace\n" @@ -253,6 +256,8 @@ usage(void) " --fno-html-spans\n" " Disable raw HTML spans\n" " --fno-html Same as --fno-html-blocks --fno-html-spans\n" + " --freddit-autolinks\n" + " Enable Reddit autolinks of the form /u/x, /r/x, u/x, r/x\n" " --ftables Enable tables\n" " --fstrikethrough Enable strikethrough spans\n" ); @@ -288,6 +293,7 @@ cmdline_callback(int opt, char const* value, void* data) case 'c': parser_flags = MD_DIALECT_COMMONMARK; break; case 'g': parser_flags = MD_DIALECT_GITHUB; break; + case 'R': parser_flags = MD_DIALECT_REDDITPOST; break; case 'E': renderer_flags |= MD_RENDER_FLAG_VERBATIM_ENTITIES; break; case 'A': parser_flags |= MD_FLAG_PERMISSIVEATXHEADERS; break; @@ -302,6 +308,7 @@ cmdline_callback(int opt, char const* value, void* data) case 'V': parser_flags |= MD_FLAG_PERMISSIVEAUTOLINKS; break; case 'T': parser_flags |= MD_FLAG_TABLES; break; case 'S': parser_flags |= MD_FLAG_STRIKETHROUGH; break; + case 'r': parser_flags |= MD_FLAG_REDDITAUTOLINKS; default: fprintf(stderr, "Illegal option: %s\n", value); diff --git a/md2html/render_html.c b/md2html/render_html.c index 6f91d0db..fa0cf9b9 100644 --- a/md2html/render_html.c +++ b/md2html/render_html.c @@ -307,7 +307,7 @@ render_open_a_span(MD_RENDER_HTML* r, const MD_SPAN_A_DETAIL* det) render_attribute(r, &det->title, render_html_escaped); } - RENDER_LITERAL(r, "\">"); + RENDER_LITERAL(r, "\" rel=\"nofollow noopener noreferrer\">"); } static void diff --git a/md4c/md4c.c b/md4c/md4c.c index 0b10c729..f5b2a667 100644 --- a/md4c/md4c.c +++ b/md4c/md4c.c @@ -2668,6 +2668,8 @@ md_build_mark_char_map(MD_CTX* ctx) ctx->mark_char_map['!'] = 1; ctx->mark_char_map[']'] = 1; ctx->mark_char_map['\0'] = 1; + if(ctx->r.flags & MD_FLAG_REDDITAUTOLINKS) + ctx->mark_char_map['/'] = 1; if(ctx->r.flags & MD_FLAG_STRIKETHROUGH) ctx->mark_char_map['~'] = 1; @@ -2884,7 +2886,29 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) /* Push a dummy as a reserve for a closer. */ PUSH_MARK('D', off, off, 0); } + off++; + continue; + } + /* A potential permissive Reddit autolink */ + if(ch == _T('/')) { + if(line->beg + 1 <= off && (CH(off - 1) == 'u' || CH(off - 1) == 'r') && + (line->beg + 1 == off || + (CH(off - 2) != '/' && (ISUNICODEPUNCTBEFORE(off - 1) || ISUNICODEWHITESPACE(off - 2)))) && + line->end > off + 1 && ISALNUM(off + 1)) { + /* u/something or r/something */ + PUSH_MARK(':', off - 1, off - 1, MD_MARK_POTENTIAL_OPENER); + /* Push a dummy as a reserve for a closer. */ + PUSH_MARK('D', off, off, 0); + } else if (line->end > off + 3) { + const char *buf = STR(off + 1); + if (buf[1] == '/' && (buf[0] == 'u' || buf[0] == 'r') && + ISALNUM(off + 3)) { + PUSH_MARK(':', off, off+1, MD_MARK_POTENTIAL_OPENER); + /* Push a dummy as a reserve for a closer. */ + PUSH_MARK('D', off, off, 0); + } + } off++; continue; } diff --git a/md4c/md4c.h b/md4c/md4c.h index 46acbeea..3908faeb 100644 --- a/md4c/md4c.h +++ b/md4c/md4c.h @@ -271,6 +271,7 @@ typedef struct MD_SPAN_IMG_DETAIL { #define MD_FLAG_PERMISSIVEAUTOLINKS (MD_FLAG_PERMISSIVEEMAILAUTOLINKS | MD_FLAG_PERMISSIVEURLAUTOLINKS | MD_FLAG_PERMISSIVEWWWAUTOLINKS) #define MD_FLAG_NOHTML (MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS) +#define MD_FLAG_REDDITAUTOLINKS 0x8000 /* Enable Reddit autolinks */ /* Convenient sets of flags corresponding to well-known Markdown dialects. * Note we may only support subset of features of the referred dialect. @@ -279,6 +280,7 @@ typedef struct MD_SPAN_IMG_DETAIL { */ #define MD_DIALECT_COMMONMARK 0 #define MD_DIALECT_GITHUB (MD_FLAG_PERMISSIVEAUTOLINKS | MD_FLAG_TABLES | MD_FLAG_STRIKETHROUGH) +#define MD_DIALECT_REDDITPOST (MD_FLAG_PERMISSIVEATXHEADERS | MD_FLAG_PERMISSIVEAUTOLINKS | MD_FLAG_NOHTML | MD_FLAG_REDDITAUTOLINKS) /* Renderer structure. */ From 4a8f087f0c6238fd05de0d845c0608af324709e9 Mon Sep 17 00:00:00 2001 From: Demi Obenour Date: Fri, 14 Jul 2017 19:12:23 -0400 Subject: [PATCH 02/17] Finish Reddit autolinks --- md4c/md4c.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/md4c/md4c.c b/md4c/md4c.c index f5b2a667..8387117d 100644 --- a/md4c/md4c.c +++ b/md4c/md4c.c @@ -3601,6 +3601,9 @@ md_analyze_permissive_url_autolink(MD_CTX* ctx, int mark_index) OFF off = opener->end; int seen_dot = FALSE; int seen_underscore_or_hyphen[2] = { FALSE, FALSE }; + if (opener->end == opener->beg) { + opener->ch = '/'; + } /* Check for domain. */ while(off < ctx->size) { @@ -3748,6 +3751,7 @@ md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, case '_': md_analyze_underscore(ctx, i); break; case '~': md_analyze_tilde(ctx, i); break; case '.': /* Pass through. */ + case '/': /* Pass through */ case ':': md_analyze_permissive_url_autolink(ctx, i); break; case '@': md_analyze_permissive_email_autolink(ctx, i); break; } @@ -3961,6 +3965,7 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) case '@': /* Permissive e-mail autolink. */ case ':': /* Permissive URL autolink. */ case '.': /* Permissive WWW autolink. */ + case '/': /* Permissive Reddit autolinks */ { const MD_MARK* opener = ((mark->flags & MD_MARK_OPENER) ? mark : &ctx->marks[mark->prev]); const MD_MARK* closer = &ctx->marks[opener->next]; @@ -3977,6 +3982,14 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) dest = ctx->buffer; } + if(opener->ch == '/') { + dest_size += 1; + MD_TEMP_BUFFER(dest_size * sizeof(CHAR)); + memcpy(ctx->buffer, _T("/"), 1 * sizeof(CHAR)); + memcpy(ctx->buffer + 1, dest, (dest_size-1) * sizeof(CHAR)); + dest = ctx->buffer; + } + MD_CHECK(md_enter_leave_span_a(ctx, (mark->flags & MD_MARK_OPENER), MD_SPAN_A, dest, dest_size, TRUE, NULL, 0)); break; From 19e6c59a28dc5c9a97653d4ab9e90d63245714cf Mon Sep 17 00:00:00 2001 From: Jimmy Xiao Date: Sun, 7 Jan 2018 19:12:34 -0700 Subject: [PATCH 03/17] Fully working Reddit slash links --- md4c/md4c.c | 173 ++++++++++++++++++++++++++++++++++++++-------------- md4c/md4c.h | 22 +++++-- 2 files changed, 144 insertions(+), 51 deletions(-) diff --git a/md4c/md4c.c b/md4c/md4c.c index d663f593..1778e7b5 100644 --- a/md4c/md4c.c +++ b/md4c/md4c.c @@ -2696,9 +2696,8 @@ md_build_mark_char_map(MD_CTX* ctx) ctx->mark_char_map['!'] = 1; ctx->mark_char_map[']'] = 1; ctx->mark_char_map['\0'] = 1; - if(ctx->r.flags & MD_FLAG_REDDITAUTOLINKS) - ctx->mark_char_map['/'] = 1; - + if (ctx->r.flags & MD_FLAG_REDDITSLASHDETECTION) + ctx->mark_char_map['/'] = 1; if(ctx->r.flags & MD_FLAG_STRIKETHROUGH) ctx->mark_char_map['~'] = 1; @@ -2923,24 +2922,39 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) if(line->beg + 1 <= off && (CH(off - 1) == 'u' || CH(off - 1) == 'r') && (line->beg + 1 == off || (CH(off - 2) != '/' && (ISUNICODEPUNCTBEFORE(off - 1) || ISUNICODEWHITESPACE(off - 2)))) && - line->end > off + 1 && ISALNUM(off + 1)) { + line->end > off + 1 && ISALNUM(off + 1)) + { + OFF index = off + 2; + while (index <= line->end) + { + if (!(ISALNUM(index) || (CH(index) == '_'))) + break; + index++; + } /* u/something or r/something */ - PUSH_MARK(':', off - 1, off - 1, MD_MARK_POTENTIAL_OPENER); - /* Push a dummy as a reserve for a closer. */ - PUSH_MARK('D', off, off, 0); - } else if (line->end > off + 3) { - const char *buf = STR(off + 1); - if (buf[1] == '/' && (buf[0] == 'u' || buf[0] == 'r') && - ISALNUM(off + 3)) { - PUSH_MARK(':', off, off+1, MD_MARK_POTENTIAL_OPENER); - /* Push a dummy as a reserve for a closer. */ - PUSH_MARK('D', off, off, 0); - } + PUSH_MARK('/', off - 1, index, MD_MARK_RESOLVED); + off = index; + } + else if (line->end > off + 3 && ((CH(off + 2) == '/') && (CH(off + 1) == 'u' || CH(off + 1) == 'r') && + ISALNUM(off + 3))) + { + OFF index = off + 4; + while (index <= line->end) + { + if (!(ISALNUM(index) || (CH(index) == '_'))) + break; + index++; + } + PUSH_MARK('/', off, index, MD_MARK_RESOLVED); + off = index; } - off++; + else + { + off++; + } continue; } - + /* A potential permissive URL autolink. */ if(ch == _T(':')) { static struct { @@ -3738,7 +3752,6 @@ md_analyze_permissive_email_autolink(MD_CTX* ctx, int mark_index) closer->end = end; md_resolve_range(ctx, NULL, mark_index, closer_index); } - static inline void md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int mark_beg, int mark_end, const CHAR* mark_chars) @@ -3993,36 +4006,106 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) case '@': /* Permissive e-mail autolink. */ case ':': /* Permissive URL autolink. */ case '.': /* Permissive WWW autolink. */ - case '/': /* Permissive Reddit autolinks */ - { - const MD_MARK* opener = ((mark->flags & MD_MARK_OPENER) ? mark : &ctx->marks[mark->prev]); - const MD_MARK* closer = &ctx->marks[opener->next]; - const CHAR* dest = STR(opener->end); - SZ dest_size = closer->beg - opener->end; - - if(opener->ch == '@' || opener->ch == '.') { - dest_size += 7; - MD_TEMP_BUFFER(dest_size * sizeof(CHAR)); - memcpy(ctx->buffer, - (opener->ch == '@' ? _T("mailto:") : _T("http://")), - 7 * sizeof(CHAR)); - memcpy(ctx->buffer + 7, dest, (dest_size-7) * sizeof(CHAR)); - dest = ctx->buffer; - } + { - if(opener->ch == '/') { - dest_size += 1; - MD_TEMP_BUFFER(dest_size * sizeof(CHAR)); - memcpy(ctx->buffer, _T("/"), 1 * sizeof(CHAR)); - memcpy(ctx->buffer + 1, dest, (dest_size-1) * sizeof(CHAR)); - dest = ctx->buffer; - } + const MD_MARK* opener = ((mark->flags & MD_MARK_OPENER) ? mark : &ctx->marks[mark->prev]); - MD_CHECK(md_enter_leave_span_a(ctx, (mark->flags & MD_MARK_OPENER), - MD_SPAN_A, dest, dest_size, TRUE, NULL, 0)); - break; - } + const MD_MARK* closer = &ctx->marks[opener->next]; + + const CHAR* dest = STR(opener->end); + + SZ dest_size = closer->beg - opener->end; + + + if (opener->ch == '@' || opener->ch == '.') { + + dest_size += 7; + + MD_TEMP_BUFFER(dest_size * sizeof(CHAR)); + + memcpy(ctx->buffer, + + (opener->ch == '@' ? _T("mailto:") : _T("http://")), + + 7 * sizeof(CHAR)); + + memcpy(ctx->buffer + 7, dest, (dest_size - 7) * sizeof(CHAR)); + + dest = ctx->buffer; + + } + + + + MD_CHECK(md_enter_leave_span_a(ctx, (mark->flags & MD_MARK_OPENER), + + MD_SPAN_A, dest, dest_size, TRUE, NULL, 0)); + + break; + + } + case '/': /* Permissive Reddit autolinks */ + { + MD_REDDIT_SLASH_DETAIL det; + if (CH(mark->beg) == '/') + { + det.name = ctx->text + mark->beg + 3; + det.size = mark->end - mark->beg - 3; + if (CH(mark->beg + 1) == 'r') + { + det.type = MD_REDDIT_SUBREDDIT; + } + else + { + det.type = MD_REDDIT_USER; + } + } + else // u/something or r/something instead of /r/something + { + det.name = ctx->text + mark->beg + 2; + det.size = mark->end - mark->beg - 2; + if (CH(mark->beg) == 'r') + { + det.type = MD_REDDIT_SUBREDDIT; + } + else + { + det.type = MD_REDDIT_USER; + } + } + if (ctx->r.flags & MD_FLAG_REDDIT_SLASHES_AS_LINKS) + { + MD_SPAN_A_DETAIL linkDet; + linkDet.href.size = (24 + (det.size)); + linkDet.href.substr_offsets = NULL; + linkDet.href.substr_types = NULL; + MD_CHAR* link = (MD_CHAR*)malloc(sizeof(MD_CHAR) * linkDet.href.size); + linkDet.href.text = link; + linkDet.title.size = 0; + linkDet.title.substr_offsets = NULL; + linkDet.title.substr_types = NULL; + linkDet.title.text = NULL; + memcpy(link, _T("https://www.reddit.com/"), sizeof(MD_CHAR) * 23); + if (det.type == MD_REDDIT_SUBREDDIT) + link[23] = _T('r'); + else + link[23] = _T('u'); + link[24] = _T('/'); + memcpy(link + 25, det.name, sizeof(MD_CHAR) * det.size); + MD_ENTER_SPAN(MD_SPAN_A, &linkDet); + MD_TEXT(text_type, STR(mark->beg), mark->end - mark->beg); + MD_LEAVE_SPAN(MD_SPAN_A, &linkDet); + free(link); + } + else + { + MD_ENTER_SPAN(MD_REDDIT_SLASH_LINK, &det); + MD_TEXT(text_type, STR(mark->beg), mark->end - mark->beg); + MD_LEAVE_SPAN(MD_REDDIT_SLASH_LINK, &det); + } + + }break; case '&': /* Entity. */ MD_TEXT(MD_TEXT_ENTITY, STR(mark->beg), mark->end - mark->beg); break; diff --git a/md4c/md4c.h b/md4c/md4c.h index d52bf9b5..fdbda7a0 100644 --- a/md4c/md4c.h +++ b/md4c/md4c.h @@ -131,7 +131,8 @@ typedef enum MD_SPANTYPE { /* ... * Note: Recognized only when MD_FLAG_STRIKETHROUGH is enabled. */ - MD_SPAN_DEL + MD_SPAN_DEL, + MD_REDDIT_SLASH_LINK } MD_SPANTYPE; /* Text is the actual textual contents of span. */ @@ -172,8 +173,10 @@ typedef enum MD_TEXTTYPE { * The text contains verbatim '\n' for the new lines. */ MD_TEXT_HTML } MD_TEXTTYPE; - - +typedef enum MD_REDDIT_SLASH_TYPE +{ + MD_REDDIT_USER, MD_REDDIT_SUBREDDIT +} MD_REDDIT_SLASH_TYPE; /* Alignment enumeration. */ typedef enum MD_ALIGN { MD_ALIGN_DEFAULT = 0, /* When unspecified. */ @@ -245,7 +248,13 @@ typedef struct MD_SPAN_A_DETAIL { MD_ATTRIBUTE href; MD_ATTRIBUTE title; } MD_SPAN_A_DETAIL; - +typedef struct MD_REDDIT_SLASH_DETAIL +{ + MD_REDDIT_SLASH_TYPE type; //whether it's a user or subreddit + /*whether the name of the user or subreddit starts two or three characters away from the beginning. To get a pointer to the name text + offset*/ + unsigned char size; //length of the whole thing, including the /r/ part. + MD_CHAR * name; +}MD_REDDIT_SLASH_DETAIL; /* Detailed info for MD_SPAN_IMG. */ typedef struct MD_SPAN_IMG_DETAIL { MD_ATTRIBUTE src; @@ -271,7 +280,8 @@ typedef struct MD_SPAN_IMG_DETAIL { #define MD_FLAG_PERMISSIVEAUTOLINKS (MD_FLAG_PERMISSIVEEMAILAUTOLINKS | MD_FLAG_PERMISSIVEURLAUTOLINKS | MD_FLAG_PERMISSIVEWWWAUTOLINKS) #define MD_FLAG_NOHTML (MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS) -#define MD_FLAG_REDDITAUTOLINKS 0x8000 /* Enable Reddit autolinks */ +#define MD_FLAG_REDDITSLASHDETECTION 0x8000 /* Enable Reddit autolinks */ +#define MD_FLAG_REDDIT_SLASHES_AS_LINKS 0x4000 //Instead of making Reddit links into special spans, make them into web links /* Convenient sets of flags corresponding to well-known Markdown dialects. * Note we may only support subset of features of the referred dialect. @@ -280,7 +290,7 @@ typedef struct MD_SPAN_IMG_DETAIL { */ #define MD_DIALECT_COMMONMARK 0 #define MD_DIALECT_GITHUB (MD_FLAG_PERMISSIVEAUTOLINKS | MD_FLAG_TABLES | MD_FLAG_STRIKETHROUGH) -#define MD_DIALECT_REDDITPOST (MD_FLAG_PERMISSIVEATXHEADERS | MD_FLAG_PERMISSIVEAUTOLINKS | MD_FLAG_NOHTML | MD_FLAG_REDDITAUTOLINKS) +#define MD_DIALECT_REDDITPOST (MD_FLAG_PERMISSIVEATXHEADERS | MD_FLAG_PERMISSIVEAUTOLINKS | MD_FLAG_NOHTML | MD_FLAG_REDDITSLASHDETECTION | MD_FLAG_STRIKETHROUGH) /* Renderer structure. */ From c686873107c7faca6835008c770c25176f42ccd8 Mon Sep 17 00:00:00 2001 From: Jimmy Xiao Date: Sun, 7 Jan 2018 19:37:17 -0700 Subject: [PATCH 04/17] Update md2html.c --- md2html/md2html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/md2html/md2html.c b/md2html/md2html.c index 02f84c3f..a3fd660c 100644 --- a/md2html/md2html.c +++ b/md2html/md2html.c @@ -308,7 +308,7 @@ cmdline_callback(int opt, char const* value, void* data) case 'V': parser_flags |= MD_FLAG_PERMISSIVEAUTOLINKS; break; case 'T': parser_flags |= MD_FLAG_TABLES; break; case 'S': parser_flags |= MD_FLAG_STRIKETHROUGH; break; - case 'r': parser_flags |= MD_FLAG_REDDITAUTOLINKS; + case 'r': parser_flags |= MD_FLAG_REDDITSLASHDETECTION; default: fprintf(stderr, "Illegal option: %s\n", value); From 0129aa521488b19cb321ec6dae2d4727d1d2835c Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sun, 7 Jan 2018 20:02:59 -0700 Subject: [PATCH 05/17] undo this because it breaks tests --- md2html/render_html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/md2html/render_html.c b/md2html/render_html.c index a079e6fd..8f0b22c0 100644 --- a/md2html/render_html.c +++ b/md2html/render_html.c @@ -307,7 +307,7 @@ render_open_a_span(MD_RENDER_HTML* r, const MD_SPAN_A_DETAIL* det) render_attribute(r, &det->title, render_html_escaped); } - RENDER_LITERAL(r, "\" rel=\"nofollow noopener noreferrer\">"); + RENDER_LITERAL(r, "\">"); } static void From 0d5d4954754300028eea10c08e948e8252092178 Mon Sep 17 00:00:00 2001 From: Jimmy Xiao Date: Sun, 7 Jan 2018 20:25:05 -0700 Subject: [PATCH 06/17] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6a77a338..65c443c5 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,8 @@ some extensions or allowing some deviations from the specification. * With the flag `MD_FLAG_NOINDENTEDCODEBLOCKS`, indented code blocks are disabled. + + * With the flag `MD_FLAG_REDDITSLASHDETECTION`, Reddit subreddit and user links such as r/test or /u/me are detected ## Input/Output Encoding From fda1114303ecb5e0f4379343443514d2331d114e Mon Sep 17 00:00:00 2001 From: Jimmy Xiao Date: Sun, 7 Jan 2018 20:43:16 -0700 Subject: [PATCH 07/17] fix some comments: --- md4c/md4c.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/md4c/md4c.h b/md4c/md4c.h index fdbda7a0..3ac15960 100644 --- a/md4c/md4c.h +++ b/md4c/md4c.h @@ -251,8 +251,7 @@ typedef struct MD_SPAN_A_DETAIL { typedef struct MD_REDDIT_SLASH_DETAIL { MD_REDDIT_SLASH_TYPE type; //whether it's a user or subreddit - /*whether the name of the user or subreddit starts two or three characters away from the beginning. To get a pointer to the name text + offset*/ - unsigned char size; //length of the whole thing, including the /r/ part. + unsigned char size; MD_CHAR * name; }MD_REDDIT_SLASH_DETAIL; /* Detailed info for MD_SPAN_IMG. */ From 93e9afdc318616c795db63b45a3069b352c8daf1 Mon Sep 17 00:00:00 2001 From: Jimmy Xiao Date: Mon, 8 Jan 2018 16:33:17 -0700 Subject: [PATCH 08/17] change Reddit flag name --- md4c/md4c.c | 2 +- md4c/md4c.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/md4c/md4c.c b/md4c/md4c.c index 1778e7b5..d1b41d35 100644 --- a/md4c/md4c.c +++ b/md4c/md4c.c @@ -2696,7 +2696,7 @@ md_build_mark_char_map(MD_CTX* ctx) ctx->mark_char_map['!'] = 1; ctx->mark_char_map[']'] = 1; ctx->mark_char_map['\0'] = 1; - if (ctx->r.flags & MD_FLAG_REDDITSLASHDETECTION) + if (ctx->r.flags & MD_FLAG_REDDITAUTOLINKS) ctx->mark_char_map['/'] = 1; if(ctx->r.flags & MD_FLAG_STRIKETHROUGH) ctx->mark_char_map['~'] = 1; diff --git a/md4c/md4c.h b/md4c/md4c.h index 3ac15960..e16bcf27 100644 --- a/md4c/md4c.h +++ b/md4c/md4c.h @@ -279,7 +279,7 @@ typedef struct MD_SPAN_IMG_DETAIL { #define MD_FLAG_PERMISSIVEAUTOLINKS (MD_FLAG_PERMISSIVEEMAILAUTOLINKS | MD_FLAG_PERMISSIVEURLAUTOLINKS | MD_FLAG_PERMISSIVEWWWAUTOLINKS) #define MD_FLAG_NOHTML (MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS) -#define MD_FLAG_REDDITSLASHDETECTION 0x8000 /* Enable Reddit autolinks */ +#define MD_FLAG_REDDITAUTOLINKS 0x8000 /* Enable Reddit autolinks */ #define MD_FLAG_REDDIT_SLASHES_AS_LINKS 0x4000 //Instead of making Reddit links into special spans, make them into web links /* Convenient sets of flags corresponding to well-known Markdown dialects. @@ -289,7 +289,7 @@ typedef struct MD_SPAN_IMG_DETAIL { */ #define MD_DIALECT_COMMONMARK 0 #define MD_DIALECT_GITHUB (MD_FLAG_PERMISSIVEAUTOLINKS | MD_FLAG_TABLES | MD_FLAG_STRIKETHROUGH) -#define MD_DIALECT_REDDITPOST (MD_FLAG_PERMISSIVEATXHEADERS | MD_FLAG_PERMISSIVEAUTOLINKS | MD_FLAG_NOHTML | MD_FLAG_REDDITSLASHDETECTION | MD_FLAG_STRIKETHROUGH) +#define MD_DIALECT_REDDITPOST (MD_FLAG_PERMISSIVEATXHEADERS | MD_FLAG_PERMISSIVEAUTOLINKS | MD_FLAG_NOHTML | MD_FLAG_REDDITAUTOLINKS | MD_FLAG_STRIKETHROUGH) /* Renderer structure. */ From 6bd03e7fe5fbc2933d3599467344bb4cedb7d638 Mon Sep 17 00:00:00 2001 From: Jimmy Xiao Date: Mon, 8 Jan 2018 16:34:34 -0700 Subject: [PATCH 09/17] Remove Reddit autolinks as web links option from md4c --- md4c/md4c.c | 36 ++++-------------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/md4c/md4c.c b/md4c/md4c.c index d1b41d35..cfa34815 100644 --- a/md4c/md4c.c +++ b/md4c/md4c.c @@ -4045,7 +4045,7 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) break; } - case '/': /* Permissive Reddit autolinks */ + case '/': /* Permissive Reddit autolinks */ { MD_REDDIT_SLASH_DETAIL det; if (CH(mark->beg) == '/') @@ -4074,37 +4074,9 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) det.type = MD_REDDIT_USER; } } - if (ctx->r.flags & MD_FLAG_REDDIT_SLASHES_AS_LINKS) - { - MD_SPAN_A_DETAIL linkDet; - linkDet.href.size = (24 + (det.size)); - linkDet.href.substr_offsets = NULL; - linkDet.href.substr_types = NULL; - MD_CHAR* link = (MD_CHAR*)malloc(sizeof(MD_CHAR) * linkDet.href.size); - linkDet.href.text = link; - linkDet.title.size = 0; - linkDet.title.substr_offsets = NULL; - linkDet.title.substr_types = NULL; - linkDet.title.text = NULL; - memcpy(link, _T("https://www.reddit.com/"), sizeof(MD_CHAR) * 23); - if (det.type == MD_REDDIT_SUBREDDIT) - link[23] = _T('r'); - else - link[23] = _T('u'); - link[24] = _T('/'); - memcpy(link + 25, det.name, sizeof(MD_CHAR) * det.size); - MD_ENTER_SPAN(MD_SPAN_A, &linkDet); - MD_TEXT(text_type, STR(mark->beg), mark->end - mark->beg); - MD_LEAVE_SPAN(MD_SPAN_A, &linkDet); - free(link); - } - else - { - MD_ENTER_SPAN(MD_REDDIT_SLASH_LINK, &det); - MD_TEXT(text_type, STR(mark->beg), mark->end - mark->beg); - MD_LEAVE_SPAN(MD_REDDIT_SLASH_LINK, &det); - } - + MD_ENTER_SPAN(MD_REDDIT_SLASH_LINK, &det); + MD_TEXT(text_type, STR(mark->beg), mark->end - mark->beg); + MD_LEAVE_SPAN(MD_REDDIT_SLASH_LINK, &det); }break; case '&': /* Entity. */ MD_TEXT(MD_TEXT_ENTITY, STR(mark->beg), mark->end - mark->beg); From 44860406d3fc903d1eec93606b1844eae287c5bf Mon Sep 17 00:00:00 2001 From: Jimmy Xiao Date: Mon, 8 Jan 2018 16:36:48 -0700 Subject: [PATCH 10/17] untabify --- md4c/md4c.c | 156 ++++++++++++++++++++++++++-------------------------- md4c/md4c.h | 12 ++-- 2 files changed, 84 insertions(+), 84 deletions(-) diff --git a/md4c/md4c.c b/md4c/md4c.c index cfa34815..4f667889 100644 --- a/md4c/md4c.c +++ b/md4c/md4c.c @@ -2696,8 +2696,8 @@ md_build_mark_char_map(MD_CTX* ctx) ctx->mark_char_map['!'] = 1; ctx->mark_char_map[']'] = 1; ctx->mark_char_map['\0'] = 1; - if (ctx->r.flags & MD_FLAG_REDDITAUTOLINKS) - ctx->mark_char_map['/'] = 1; + if (ctx->r.flags & MD_FLAG_REDDITAUTOLINKS) + ctx->mark_char_map['/'] = 1; if(ctx->r.flags & MD_FLAG_STRIKETHROUGH) ctx->mark_char_map['~'] = 1; @@ -2923,38 +2923,38 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) (line->beg + 1 == off || (CH(off - 2) != '/' && (ISUNICODEPUNCTBEFORE(off - 1) || ISUNICODEWHITESPACE(off - 2)))) && line->end > off + 1 && ISALNUM(off + 1)) - { - OFF index = off + 2; - while (index <= line->end) - { - if (!(ISALNUM(index) || (CH(index) == '_'))) - break; - index++; - } + { + OFF index = off + 2; + while (index <= line->end) + { + if (!(ISALNUM(index) || (CH(index) == '_'))) + break; + index++; + } /* u/something or r/something */ PUSH_MARK('/', off - 1, index, MD_MARK_RESOLVED); - off = index; + off = index; } - else if (line->end > off + 3 && ((CH(off + 2) == '/') && (CH(off + 1) == 'u' || CH(off + 1) == 'r') && - ISALNUM(off + 3))) - { - OFF index = off + 4; - while (index <= line->end) - { - if (!(ISALNUM(index) || (CH(index) == '_'))) - break; - index++; - } + else if (line->end > off + 3 && ((CH(off + 2) == '/') && (CH(off + 1) == 'u' || CH(off + 1) == 'r') && + ISALNUM(off + 3))) + { + OFF index = off + 4; + while (index <= line->end) + { + if (!(ISALNUM(index) || (CH(index) == '_'))) + break; + index++; + } PUSH_MARK('/', off, index, MD_MARK_RESOLVED); - off = index; + off = index; + } + else + { + off++; } - else - { - off++; - } continue; } - + /* A potential permissive URL autolink. */ if(ch == _T(':')) { static struct { @@ -4006,78 +4006,78 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) case '@': /* Permissive e-mail autolink. */ case ':': /* Permissive URL autolink. */ case '.': /* Permissive WWW autolink. */ - { + { - const MD_MARK* opener = ((mark->flags & MD_MARK_OPENER) ? mark : &ctx->marks[mark->prev]); + const MD_MARK* opener = ((mark->flags & MD_MARK_OPENER) ? mark : &ctx->marks[mark->prev]); - const MD_MARK* closer = &ctx->marks[opener->next]; + const MD_MARK* closer = &ctx->marks[opener->next]; - const CHAR* dest = STR(opener->end); + const CHAR* dest = STR(opener->end); - SZ dest_size = closer->beg - opener->end; + SZ dest_size = closer->beg - opener->end; - if (opener->ch == '@' || opener->ch == '.') { + if (opener->ch == '@' || opener->ch == '.') { - dest_size += 7; + dest_size += 7; - MD_TEMP_BUFFER(dest_size * sizeof(CHAR)); + MD_TEMP_BUFFER(dest_size * sizeof(CHAR)); - memcpy(ctx->buffer, + memcpy(ctx->buffer, - (opener->ch == '@' ? _T("mailto:") : _T("http://")), + (opener->ch == '@' ? _T("mailto:") : _T("http://")), - 7 * sizeof(CHAR)); + 7 * sizeof(CHAR)); - memcpy(ctx->buffer + 7, dest, (dest_size - 7) * sizeof(CHAR)); + memcpy(ctx->buffer + 7, dest, (dest_size - 7) * sizeof(CHAR)); - dest = ctx->buffer; + dest = ctx->buffer; - } + } - MD_CHECK(md_enter_leave_span_a(ctx, (mark->flags & MD_MARK_OPENER), + MD_CHECK(md_enter_leave_span_a(ctx, (mark->flags & MD_MARK_OPENER), - MD_SPAN_A, dest, dest_size, TRUE, NULL, 0)); + MD_SPAN_A, dest, dest_size, TRUE, NULL, 0)); - break; + break; - } - case '/': /* Permissive Reddit autolinks */ - { - MD_REDDIT_SLASH_DETAIL det; - if (CH(mark->beg) == '/') - { - det.name = ctx->text + mark->beg + 3; - det.size = mark->end - mark->beg - 3; - if (CH(mark->beg + 1) == 'r') - { - det.type = MD_REDDIT_SUBREDDIT; - } - else - { - det.type = MD_REDDIT_USER; - } - } - else // u/something or r/something instead of /r/something - { - det.name = ctx->text + mark->beg + 2; - det.size = mark->end - mark->beg - 2; - if (CH(mark->beg) == 'r') - { - det.type = MD_REDDIT_SUBREDDIT; - } - else - { - det.type = MD_REDDIT_USER; - } - } - MD_ENTER_SPAN(MD_REDDIT_SLASH_LINK, &det); - MD_TEXT(text_type, STR(mark->beg), mark->end - mark->beg); - MD_LEAVE_SPAN(MD_REDDIT_SLASH_LINK, &det); - }break; + } + case '/': /* Permissive Reddit autolinks */ + { + MD_REDDIT_SLASH_DETAIL det; + if (CH(mark->beg) == '/') + { + det.name = ctx->text + mark->beg + 3; + det.size = mark->end - mark->beg - 3; + if (CH(mark->beg + 1) == 'r') + { + det.type = MD_REDDIT_SUBREDDIT; + } + else + { + det.type = MD_REDDIT_USER; + } + } + else // u/something or r/something instead of /r/something + { + det.name = ctx->text + mark->beg + 2; + det.size = mark->end - mark->beg - 2; + if (CH(mark->beg) == 'r') + { + det.type = MD_REDDIT_SUBREDDIT; + } + else + { + det.type = MD_REDDIT_USER; + } + } + MD_ENTER_SPAN(MD_REDDIT_SLASH_LINK, &det); + MD_TEXT(text_type, STR(mark->beg), mark->end - mark->beg); + MD_LEAVE_SPAN(MD_REDDIT_SLASH_LINK, &det); + }break; case '&': /* Entity. */ MD_TEXT(MD_TEXT_ENTITY, STR(mark->beg), mark->end - mark->beg); break; diff --git a/md4c/md4c.h b/md4c/md4c.h index e16bcf27..e8ff3087 100644 --- a/md4c/md4c.h +++ b/md4c/md4c.h @@ -132,7 +132,7 @@ typedef enum MD_SPANTYPE { * Note: Recognized only when MD_FLAG_STRIKETHROUGH is enabled. */ MD_SPAN_DEL, - MD_REDDIT_SLASH_LINK + MD_REDDIT_SLASH_LINK } MD_SPANTYPE; /* Text is the actual textual contents of span. */ @@ -175,7 +175,7 @@ typedef enum MD_TEXTTYPE { } MD_TEXTTYPE; typedef enum MD_REDDIT_SLASH_TYPE { - MD_REDDIT_USER, MD_REDDIT_SUBREDDIT + MD_REDDIT_USER, MD_REDDIT_SUBREDDIT } MD_REDDIT_SLASH_TYPE; /* Alignment enumeration. */ typedef enum MD_ALIGN { @@ -250,9 +250,9 @@ typedef struct MD_SPAN_A_DETAIL { } MD_SPAN_A_DETAIL; typedef struct MD_REDDIT_SLASH_DETAIL { - MD_REDDIT_SLASH_TYPE type; //whether it's a user or subreddit - unsigned char size; - MD_CHAR * name; + MD_REDDIT_SLASH_TYPE type; //whether it's a user or subreddit + unsigned char size; + MD_CHAR * name; }MD_REDDIT_SLASH_DETAIL; /* Detailed info for MD_SPAN_IMG. */ typedef struct MD_SPAN_IMG_DETAIL { @@ -280,7 +280,7 @@ typedef struct MD_SPAN_IMG_DETAIL { #define MD_FLAG_PERMISSIVEAUTOLINKS (MD_FLAG_PERMISSIVEEMAILAUTOLINKS | MD_FLAG_PERMISSIVEURLAUTOLINKS | MD_FLAG_PERMISSIVEWWWAUTOLINKS) #define MD_FLAG_NOHTML (MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS) #define MD_FLAG_REDDITAUTOLINKS 0x8000 /* Enable Reddit autolinks */ -#define MD_FLAG_REDDIT_SLASHES_AS_LINKS 0x4000 //Instead of making Reddit links into special spans, make them into web links + /* Convenient sets of flags corresponding to well-known Markdown dialects. * Note we may only support subset of features of the referred dialect. From f1e5e0ee3c93215f0f6b716fbb7e90f716114722 Mon Sep 17 00:00:00 2001 From: Jimmy Xiao Date: Mon, 8 Jan 2018 16:39:24 -0700 Subject: [PATCH 11/17] rename Reddit dialect option to ensure consistency --- md4c/md4c.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/md4c/md4c.h b/md4c/md4c.h index e8ff3087..aef3bdef 100644 --- a/md4c/md4c.h +++ b/md4c/md4c.h @@ -289,7 +289,7 @@ typedef struct MD_SPAN_IMG_DETAIL { */ #define MD_DIALECT_COMMONMARK 0 #define MD_DIALECT_GITHUB (MD_FLAG_PERMISSIVEAUTOLINKS | MD_FLAG_TABLES | MD_FLAG_STRIKETHROUGH) -#define MD_DIALECT_REDDITPOST (MD_FLAG_PERMISSIVEATXHEADERS | MD_FLAG_PERMISSIVEAUTOLINKS | MD_FLAG_NOHTML | MD_FLAG_REDDITAUTOLINKS | MD_FLAG_STRIKETHROUGH) +#define MD_DIALECT_REDDIT (MD_FLAG_PERMISSIVEATXHEADERS | MD_FLAG_PERMISSIVEAUTOLINKS | MD_FLAG_NOHTML | MD_FLAG_REDDITAUTOLINKS | MD_FLAG_STRIKETHROUGH) /* Renderer structure. */ From aff66bf520f47bbb563431a4d1a06dabb3326f60 Mon Sep 17 00:00:00 2001 From: Jimmy Xiao Date: Mon, 8 Jan 2018 16:52:04 -0700 Subject: [PATCH 12/17] change md2html flags --- md2html/md2html.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/md2html/md2html.c b/md2html/md2html.c index a3fd660c..f7d02764 100644 --- a/md2html/md2html.c +++ b/md2html/md2html.c @@ -195,7 +195,7 @@ static const option cmdline_options[] = { { "version", 'v', 'v', OPTION_ARG_NONE }, { "commonmark", 0, 'c', OPTION_ARG_NONE }, { "github", 0, 'g', OPTION_ARG_NONE }, - { "reddit", 0, 'R', OPTION_ARG_NONE }, + { "reddit", 0, 'r', OPTION_ARG_NONE }, { "fverbatim-entities", 0, 'E', OPTION_ARG_NONE }, { "fpermissive-atx-headers", 0, 'A', OPTION_ARG_NONE }, { "fpermissive-url-autolinks", 0, 'U', OPTION_ARG_NONE }, @@ -209,7 +209,7 @@ static const option cmdline_options[] = { { "fcollapse-whitespace", 0, 'W', OPTION_ARG_NONE }, { "ftables", 0, 'T', OPTION_ARG_NONE }, { "fstrikethrough", 0, 'S', OPTION_ARG_NONE }, - { "freddit-autolinks", 0, 'r', OPTION_ARG_NONE }, + { "freddit-autolinks", 0, 'R', OPTION_ARG_NONE }, { 0 } }; @@ -293,7 +293,7 @@ cmdline_callback(int opt, char const* value, void* data) case 'c': parser_flags = MD_DIALECT_COMMONMARK; break; case 'g': parser_flags = MD_DIALECT_GITHUB; break; - case 'R': parser_flags = MD_DIALECT_REDDITPOST; break; + case 'r': parser_flags = MD_DIALECT_REDDITPOST; break; case 'E': renderer_flags |= MD_RENDER_FLAG_VERBATIM_ENTITIES; break; case 'A': parser_flags |= MD_FLAG_PERMISSIVEATXHEADERS; break; @@ -308,7 +308,7 @@ cmdline_callback(int opt, char const* value, void* data) case 'V': parser_flags |= MD_FLAG_PERMISSIVEAUTOLINKS; break; case 'T': parser_flags |= MD_FLAG_TABLES; break; case 'S': parser_flags |= MD_FLAG_STRIKETHROUGH; break; - case 'r': parser_flags |= MD_FLAG_REDDITSLASHDETECTION; + case 'R': parser_flags |= MD_FLAG_REDDITSLASHDETECTION; break; default: fprintf(stderr, "Illegal option: %s\n", value); From 5233d98d183d246738eff9816eed7c1adddf43aa Mon Sep 17 00:00:00 2001 From: Jimmy Xiao Date: Mon, 8 Jan 2018 18:09:07 -0700 Subject: [PATCH 13/17] add reddit autolinking to md2html and add tests --- test/reddit-autolinks.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 test/reddit-autolinks.txt diff --git a/test/reddit-autolinks.txt b/test/reddit-autolinks.txt new file mode 100644 index 00000000..996e3199 --- /dev/null +++ b/test/reddit-autolinks.txt @@ -0,0 +1,22 @@ + +# Reddit Autolinks + +With the flag `MD_FLAG_REDDITAUTOLINKS`, MD4C enables extension for recognition Reddit usernames and subreddits. + +For reference, here is snudown's (Reddit's markdown parser) implementation [link](https://github.com/reddit/snudown/blob/master/src/autolink.c). + +Reddit autolinks can be prefixed by a a forward slash or not: r/test and /r/test both work. A link ends when a non-alphanumeric character is hit. The only such character allowed it an underscore. + +```````````````````````````````` example +Here is a link to /r/askreddit by u/me. +. +

Here is a link to /r/askreddit by u/me.

+```````````````````````````````` + +A link can show up in the middle of the word if prefixed by a forward slash (you don't need a whitespace before). + +```````````````````````````````` example +World/r/news vs /r/worldnew;s +. +

World/r/news vs /r/worldnew;s

+```````````````````````````````` \ No newline at end of file From 70e8801ab12aeecad52f10cecd94b77bd5f46000 Mon Sep 17 00:00:00 2001 From: Jimmy Xiao Date: Mon, 8 Jan 2018 18:10:54 -0700 Subject: [PATCH 14/17] oops forgot to add some stuff to the last commit --- md2html/md2html.c | 4 ++-- md2html/render_html.c | 18 ++++++++++++++++++ scripts/run-tests.sh | 5 +++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/md2html/md2html.c b/md2html/md2html.c index f7d02764..32c7ea65 100644 --- a/md2html/md2html.c +++ b/md2html/md2html.c @@ -293,7 +293,7 @@ cmdline_callback(int opt, char const* value, void* data) case 'c': parser_flags = MD_DIALECT_COMMONMARK; break; case 'g': parser_flags = MD_DIALECT_GITHUB; break; - case 'r': parser_flags = MD_DIALECT_REDDITPOST; break; + case 'r': parser_flags = MD_DIALECT_REDDIT; break; case 'E': renderer_flags |= MD_RENDER_FLAG_VERBATIM_ENTITIES; break; case 'A': parser_flags |= MD_FLAG_PERMISSIVEATXHEADERS; break; @@ -308,7 +308,7 @@ cmdline_callback(int opt, char const* value, void* data) case 'V': parser_flags |= MD_FLAG_PERMISSIVEAUTOLINKS; break; case 'T': parser_flags |= MD_FLAG_TABLES; break; case 'S': parser_flags |= MD_FLAG_STRIKETHROUGH; break; - case 'R': parser_flags |= MD_FLAG_REDDITSLASHDETECTION; break; + case 'R': parser_flags |= MD_FLAG_REDDITAUTOLINKS; break; default: fprintf(stderr, "Illegal option: %s\n", value); diff --git a/md2html/render_html.c b/md2html/render_html.c index 8f0b22c0..3ca58833 100644 --- a/md2html/render_html.c +++ b/md2html/render_html.c @@ -310,6 +310,22 @@ render_open_a_span(MD_RENDER_HTML* r, const MD_SPAN_A_DETAIL* det) RENDER_LITERAL(r, "\">"); } +static void +render_reddit_link(MD_RENDER_HTML* r, const MD_REDDIT_SLASH_DETAIL* det) +{ + RENDER_LITERAL(r, "type == MD_REDDIT_SUBREDDIT) + { + RENDER_LITERAL(r, "r/"); + } + else + { + RENDER_LITERAL(r, "u/"); + } + render_text(r, det->name, det->size); + RENDER_LITERAL(r, "\">"); +} + static void render_open_img_span(MD_RENDER_HTML* r, const MD_SPAN_IMG_DETAIL* det) { @@ -413,6 +429,7 @@ enter_span_callback(MD_SPANTYPE type, void* detail, void* userdata) case MD_SPAN_IMG: render_open_img_span(r, (MD_SPAN_IMG_DETAIL*) detail); break; case MD_SPAN_CODE: RENDER_LITERAL(r, ""); break; case MD_SPAN_DEL: RENDER_LITERAL(r, ""); break; + case MD_REDDIT_SLASH_LINK: render_reddit_link(r, (MD_REDDIT_SLASH_DETAIL*)detail); break; } return 0; @@ -438,6 +455,7 @@ leave_span_callback(MD_SPANTYPE type, void* detail, void* userdata) case MD_SPAN_IMG: /*noop, handled above*/ break; case MD_SPAN_CODE: RENDER_LITERAL(r, ""); break; case MD_SPAN_DEL: RENDER_LITERAL(r, ""); break; + case MD_REDDIT_SLASH_LINK: RENDER_LITERAL(r, ""); break; } return 0; diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index cc62111b..f5f45e23 100755 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -54,6 +54,11 @@ echo echo "Strikethrough extension:" $PYTHON "$TEST_DIR/spec_tests.py" -s "$TEST_DIR/strikethrough.txt" -p "$PROGRAM --fstrikethrough" +echo +echo "Reddit autolinks extension:" +$PYTHON "$TEST_DIR/spec_tests.py" -s +"$TEST_DIR/reddit-autolinks.txt" -p "$PROGRAM --freddit-autolinks" + echo echo "Pathological input:" $PYTHON "$TEST_DIR/pathological_tests.py" -p "$PROGRAM" From 061d6f6dfd52b9bcb7dfc96eb79ed6c3e4e7749f Mon Sep 17 00:00:00 2001 From: Jimmy Date: Thu, 11 Jan 2018 16:40:33 -0700 Subject: [PATCH 15/17] remove extra linebreak in tests --- scripts/run-tests.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index f5f45e23..632119ae 100755 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -56,8 +56,7 @@ $PYTHON "$TEST_DIR/spec_tests.py" -s "$TEST_DIR/strikethrough.txt" -p "$PROGRAM echo echo "Reddit autolinks extension:" -$PYTHON "$TEST_DIR/spec_tests.py" -s -"$TEST_DIR/reddit-autolinks.txt" -p "$PROGRAM --freddit-autolinks" +$PYTHON "$TEST_DIR/spec_tests.py" -s "$TEST_DIR/reddit-autolinks.txt" -p "$PROGRAM --freddit-autolinks" echo echo "Pathological input:" From 3fb5f0385f46dacd5b5e13b6e439eb16615fb18c Mon Sep 17 00:00:00 2001 From: Jimmy Date: Thu, 11 Jan 2018 16:45:43 -0700 Subject: [PATCH 16/17] remove extra linebreaks --- md4c/md4c.c | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/md4c/md4c.c b/md4c/md4c.c index 4f667889..6f9bebd5 100644 --- a/md4c/md4c.c +++ b/md4c/md4c.c @@ -4007,43 +4007,21 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) case ':': /* Permissive URL autolink. */ case '.': /* Permissive WWW autolink. */ { - const MD_MARK* opener = ((mark->flags & MD_MARK_OPENER) ? mark : &ctx->marks[mark->prev]); - const MD_MARK* closer = &ctx->marks[opener->next]; - const CHAR* dest = STR(opener->end); - SZ dest_size = closer->beg - opener->end; - - - if (opener->ch == '@' || opener->ch == '.') { - dest_size += 7; - MD_TEMP_BUFFER(dest_size * sizeof(CHAR)); - memcpy(ctx->buffer, - (opener->ch == '@' ? _T("mailto:") : _T("http://")), - 7 * sizeof(CHAR)); - memcpy(ctx->buffer + 7, dest, (dest_size - 7) * sizeof(CHAR)); - dest = ctx->buffer; - } - - - - MD_CHECK(md_enter_leave_span_a(ctx, (mark->flags & MD_MARK_OPENER), - - MD_SPAN_A, dest, dest_size, TRUE, NULL, 0)); - + MD_CHECK(md_enter_leave_span_a(ctx, (mark->flags & MD_MARK_OPENER), MD_SPAN_A, dest, dest_size, TRUE, NULL, 0)); break; - } case '/': /* Permissive Reddit autolinks */ { From c959ac7c12749a44c8ed6398625a061a254bb91c Mon Sep 17 00:00:00 2001 From: Jimmy Xiao Date: Thu, 11 Jan 2018 18:07:49 -0700 Subject: [PATCH 17/17] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 65c443c5..93ad5bcf 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ some extensions or allowing some deviations from the specification. * With the flag `MD_FLAG_NOINDENTEDCODEBLOCKS`, indented code blocks are disabled. - * With the flag `MD_FLAG_REDDITSLASHDETECTION`, Reddit subreddit and user links such as r/test or /u/me are detected + * With the flag `MD_FLAG_REDDITAUTOLINKS`, Reddit subreddit and user links such as r/test or /u/me are detected ## Input/Output Encoding