Fossil SCM

Further refine the fenced code block rendering in markdown to try to comply with the CommonMark spec.

drh 2019-08-08 22:26 trunk
Commit 81caad6ce6bc412c80b0d1221ca500caad39af5da205dc679025e6233a447b26
1 file changed +36 -4
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -325,20 +325,52 @@
325325
}
326326
BLOB_APPEND_LITERAL(ob, "</a>");
327327
return 1;
328328
}
329329
330
+/* Invoked for `...` blocks where there are nSep grave accents in a
331
+** row that serve as the delimiter. According to CommonMark:
332
+**
333
+** * https://spec.commonmark.org/0.29/#fenced-code-blocks
334
+** * https://spec.commonmark.org/0.29/#code-spans
335
+**
336
+** If nSep is 1 or 2, then this is a code-span which is inline.
337
+** If nSep is 3 or more, then this is a fenced code block
338
+*/
330339
static int html_code_span(
331
- struct Blob *ob,
340
+ struct Blob *ob, /* Write the output here */
332341
struct Blob *text, /* The stuff in between the code span marks */
333342
int nSep, /* Number of grave accents marks as delimiters */
334343
void *opaque
335344
){
336
- if( text ){
337
- blob_append(ob, nSep>=3 ? "<pre>" : "<code>", -1);
345
+ if( text==0 ){
346
+ /* no-op */
347
+ }else if( nSep<=2 ){
348
+ /* One or two graves: an in-line code span */
349
+ BLOB_APPEND_LITERAL(ob, "<code>");
338350
html_escape(ob, blob_buffer(text), blob_size(text));
339
- blob_append(ob, nSep>=3 ? "</pre>" : "</code>", -1);
351
+ BLOB_APPEND_LITERAL(ob, "</code>");
352
+ }else{
353
+ /* Three or more graves: a fenced code block */
354
+ int n = blob_size(text);
355
+ const char *z = blob_buffer(text);
356
+ int i;
357
+ for(i=0; i<n && z[i]!='\n'; i++){}
358
+ if( i>=n ){
359
+ blob_appendf(ob, "<pre><code>%.*s</code></pre>", n, z);
360
+ }else{
361
+ int k, j;
362
+ i++;
363
+ for(k=0; k<i && fossil_isspace(z[k]); k++){}
364
+ if( k==i ){
365
+ blob_appendf(ob, "<pre><code>%.*s</code></pre>", n-i, z+i);
366
+ }else{
367
+ for(j=k+1; j<i && !fossil_isspace(z[j]); j++){}
368
+ blob_appendf(ob, "<pre><code class='language-%#h'>%.*s</code></pre>",
369
+ j-k, z+k, n-i, z+i);
370
+ }
371
+ }
340372
}
341373
return 1;
342374
}
343375
344376
static int html_double_emphasis(
345377
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -325,20 +325,52 @@
325 }
326 BLOB_APPEND_LITERAL(ob, "</a>");
327 return 1;
328 }
329
 
 
 
 
 
 
 
 
 
330 static int html_code_span(
331 struct Blob *ob,
332 struct Blob *text, /* The stuff in between the code span marks */
333 int nSep, /* Number of grave accents marks as delimiters */
334 void *opaque
335 ){
336 if( text ){
337 blob_append(ob, nSep>=3 ? "<pre>" : "<code>", -1);
 
 
 
338 html_escape(ob, blob_buffer(text), blob_size(text));
339 blob_append(ob, nSep>=3 ? "</pre>" : "</code>", -1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340 }
341 return 1;
342 }
343
344 static int html_double_emphasis(
345
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -325,20 +325,52 @@
325 }
326 BLOB_APPEND_LITERAL(ob, "</a>");
327 return 1;
328 }
329
330 /* Invoked for `...` blocks where there are nSep grave accents in a
331 ** row that serve as the delimiter. According to CommonMark:
332 **
333 ** * https://spec.commonmark.org/0.29/#fenced-code-blocks
334 ** * https://spec.commonmark.org/0.29/#code-spans
335 **
336 ** If nSep is 1 or 2, then this is a code-span which is inline.
337 ** If nSep is 3 or more, then this is a fenced code block
338 */
339 static int html_code_span(
340 struct Blob *ob, /* Write the output here */
341 struct Blob *text, /* The stuff in between the code span marks */
342 int nSep, /* Number of grave accents marks as delimiters */
343 void *opaque
344 ){
345 if( text==0 ){
346 /* no-op */
347 }else if( nSep<=2 ){
348 /* One or two graves: an in-line code span */
349 BLOB_APPEND_LITERAL(ob, "<code>");
350 html_escape(ob, blob_buffer(text), blob_size(text));
351 BLOB_APPEND_LITERAL(ob, "</code>");
352 }else{
353 /* Three or more graves: a fenced code block */
354 int n = blob_size(text);
355 const char *z = blob_buffer(text);
356 int i;
357 for(i=0; i<n && z[i]!='\n'; i++){}
358 if( i>=n ){
359 blob_appendf(ob, "<pre><code>%.*s</code></pre>", n, z);
360 }else{
361 int k, j;
362 i++;
363 for(k=0; k<i && fossil_isspace(z[k]); k++){}
364 if( k==i ){
365 blob_appendf(ob, "<pre><code>%.*s</code></pre>", n-i, z+i);
366 }else{
367 for(j=k+1; j<i && !fossil_isspace(z[j]); j++){}
368 blob_appendf(ob, "<pre><code class='language-%#h'>%.*s</code></pre>",
369 j-k, z+k, n-i, z+i);
370 }
371 }
372 }
373 return 1;
374 }
375
376 static int html_double_emphasis(
377

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button