Fossil SCM
Further work on the fenced code blocks of markdown. Allow blank lines in the middle of a fenced code block. And also allow ~ character (three or more) to serve as the delimiter for fenced code blocks.
Commit
c7600da4893b5ea2875bc4bb8617114e498e833c28a07c41e3233c0dddf3def8
Parent
1296ee46a3ad9f0…
2 files changed
+17
-2
+3
-3
+17
-2
| --- src/markdown.c | ||
| +++ src/markdown.c | ||
| @@ -725,18 +725,19 @@ | ||
| 725 | 725 | char *data, |
| 726 | 726 | size_t offset, |
| 727 | 727 | size_t size |
| 728 | 728 | ){ |
| 729 | 729 | size_t end, nb = 0, i, f_begin, f_end; |
| 730 | + char delim = data[0]; | |
| 730 | 731 | |
| 731 | 732 | /* counting the number of backticks in the delimiter */ |
| 732 | - while( nb<size && data[nb]=='`' ){ nb++; } | |
| 733 | + while( nb<size && data[nb]==delim ){ nb++; } | |
| 733 | 734 | |
| 734 | 735 | /* finding the next delimiter */ |
| 735 | 736 | i = 0; |
| 736 | 737 | for(end=nb; end<size && i<nb; end++){ |
| 737 | - if( data[end]=='`' ) i++; else i = 0; | |
| 738 | + if( data[end]==delim ) i++; else i = 0; | |
| 738 | 739 | } |
| 739 | 740 | if( i<nb && end>=size ) return 0; /* no matching delimiter */ |
| 740 | 741 | |
| 741 | 742 | /* trimming outside whitespaces */ |
| 742 | 743 | f_begin = nb; |
| @@ -1196,10 +1197,22 @@ | ||
| 1196 | 1197 | if( size>3 && data[0]==' ' && data[1]==' ' && data[2]==' ' && data[3]==' ' ){ |
| 1197 | 1198 | return 4; |
| 1198 | 1199 | } |
| 1199 | 1200 | return 0; |
| 1200 | 1201 | } |
| 1202 | + | |
| 1203 | +/* Return the number of characters in the delimiter of a fenced code | |
| 1204 | +** block. */ | |
| 1205 | +static size_t prefix_fencedcode(char *data, size_t size){ | |
| 1206 | + char c = data[0]; | |
| 1207 | + int nb; | |
| 1208 | + if( c!='`' && c!='~' ) return 0; | |
| 1209 | + for(nb=1; nb<size-3 && data[nb]==c; nb++){} | |
| 1210 | + if( nb<3 ) return 0; | |
| 1211 | + if( nb>=size-nb ) return 0; | |
| 1212 | + return nb; | |
| 1213 | +} | |
| 1201 | 1214 | |
| 1202 | 1215 | /* prefix_oli -- returns ordered list item prefix */ |
| 1203 | 1216 | static size_t prefix_oli(char *data, size_t size){ |
| 1204 | 1217 | size_t i = 0; |
| 1205 | 1218 | if( i<size && data[i]==' ') i++; |
| @@ -2013,10 +2026,12 @@ | ||
| 2013 | 2026 | beg += parse_list(ob, rndr, txt_data, end, 0); |
| 2014 | 2027 | }else if( prefix_oli(txt_data, end) ){ |
| 2015 | 2028 | beg += parse_list(ob, rndr, txt_data, end, MKD_LIST_ORDERED); |
| 2016 | 2029 | }else if( has_table && is_tableline(txt_data, end) ){ |
| 2017 | 2030 | beg += parse_table(ob, rndr, txt_data, end); |
| 2031 | + }else if( prefix_fencedcode(txt_data, end) ){ | |
| 2032 | + beg += char_codespan(ob, rndr, txt_data, 0, end); | |
| 2018 | 2033 | }else{ |
| 2019 | 2034 | beg += parse_paragraph(ob, rndr, txt_data, end); |
| 2020 | 2035 | } |
| 2021 | 2036 | } |
| 2022 | 2037 | } |
| 2023 | 2038 |
| --- src/markdown.c | |
| +++ src/markdown.c | |
| @@ -725,18 +725,19 @@ | |
| 725 | char *data, |
| 726 | size_t offset, |
| 727 | size_t size |
| 728 | ){ |
| 729 | size_t end, nb = 0, i, f_begin, f_end; |
| 730 | |
| 731 | /* counting the number of backticks in the delimiter */ |
| 732 | while( nb<size && data[nb]=='`' ){ nb++; } |
| 733 | |
| 734 | /* finding the next delimiter */ |
| 735 | i = 0; |
| 736 | for(end=nb; end<size && i<nb; end++){ |
| 737 | if( data[end]=='`' ) i++; else i = 0; |
| 738 | } |
| 739 | if( i<nb && end>=size ) return 0; /* no matching delimiter */ |
| 740 | |
| 741 | /* trimming outside whitespaces */ |
| 742 | f_begin = nb; |
| @@ -1196,10 +1197,22 @@ | |
| 1196 | if( size>3 && data[0]==' ' && data[1]==' ' && data[2]==' ' && data[3]==' ' ){ |
| 1197 | return 4; |
| 1198 | } |
| 1199 | return 0; |
| 1200 | } |
| 1201 | |
| 1202 | /* prefix_oli -- returns ordered list item prefix */ |
| 1203 | static size_t prefix_oli(char *data, size_t size){ |
| 1204 | size_t i = 0; |
| 1205 | if( i<size && data[i]==' ') i++; |
| @@ -2013,10 +2026,12 @@ | |
| 2013 | beg += parse_list(ob, rndr, txt_data, end, 0); |
| 2014 | }else if( prefix_oli(txt_data, end) ){ |
| 2015 | beg += parse_list(ob, rndr, txt_data, end, MKD_LIST_ORDERED); |
| 2016 | }else if( has_table && is_tableline(txt_data, end) ){ |
| 2017 | beg += parse_table(ob, rndr, txt_data, end); |
| 2018 | }else{ |
| 2019 | beg += parse_paragraph(ob, rndr, txt_data, end); |
| 2020 | } |
| 2021 | } |
| 2022 | } |
| 2023 |
| --- src/markdown.c | |
| +++ src/markdown.c | |
| @@ -725,18 +725,19 @@ | |
| 725 | char *data, |
| 726 | size_t offset, |
| 727 | size_t size |
| 728 | ){ |
| 729 | size_t end, nb = 0, i, f_begin, f_end; |
| 730 | char delim = data[0]; |
| 731 | |
| 732 | /* counting the number of backticks in the delimiter */ |
| 733 | while( nb<size && data[nb]==delim ){ nb++; } |
| 734 | |
| 735 | /* finding the next delimiter */ |
| 736 | i = 0; |
| 737 | for(end=nb; end<size && i<nb; end++){ |
| 738 | if( data[end]==delim ) i++; else i = 0; |
| 739 | } |
| 740 | if( i<nb && end>=size ) return 0; /* no matching delimiter */ |
| 741 | |
| 742 | /* trimming outside whitespaces */ |
| 743 | f_begin = nb; |
| @@ -1196,10 +1197,22 @@ | |
| 1197 | if( size>3 && data[0]==' ' && data[1]==' ' && data[2]==' ' && data[3]==' ' ){ |
| 1198 | return 4; |
| 1199 | } |
| 1200 | return 0; |
| 1201 | } |
| 1202 | |
| 1203 | /* Return the number of characters in the delimiter of a fenced code |
| 1204 | ** block. */ |
| 1205 | static size_t prefix_fencedcode(char *data, size_t size){ |
| 1206 | char c = data[0]; |
| 1207 | int nb; |
| 1208 | if( c!='`' && c!='~' ) return 0; |
| 1209 | for(nb=1; nb<size-3 && data[nb]==c; nb++){} |
| 1210 | if( nb<3 ) return 0; |
| 1211 | if( nb>=size-nb ) return 0; |
| 1212 | return nb; |
| 1213 | } |
| 1214 | |
| 1215 | /* prefix_oli -- returns ordered list item prefix */ |
| 1216 | static size_t prefix_oli(char *data, size_t size){ |
| 1217 | size_t i = 0; |
| 1218 | if( i<size && data[i]==' ') i++; |
| @@ -2013,10 +2026,12 @@ | |
| 2026 | beg += parse_list(ob, rndr, txt_data, end, 0); |
| 2027 | }else if( prefix_oli(txt_data, end) ){ |
| 2028 | beg += parse_list(ob, rndr, txt_data, end, MKD_LIST_ORDERED); |
| 2029 | }else if( has_table && is_tableline(txt_data, end) ){ |
| 2030 | beg += parse_table(ob, rndr, txt_data, end); |
| 2031 | }else if( prefix_fencedcode(txt_data, end) ){ |
| 2032 | beg += char_codespan(ob, rndr, txt_data, 0, end); |
| 2033 | }else{ |
| 2034 | beg += parse_paragraph(ob, rndr, txt_data, end); |
| 2035 | } |
| 2036 | } |
| 2037 | } |
| 2038 |
+3
-3
| --- src/markdown_html.c | ||
| +++ src/markdown_html.c | ||
| @@ -354,20 +354,20 @@ | ||
| 354 | 354 | int n = blob_size(text); |
| 355 | 355 | const char *z = blob_buffer(text); |
| 356 | 356 | int i; |
| 357 | 357 | for(i=0; i<n && z[i]!='\n'; i++){} |
| 358 | 358 | if( i>=n ){ |
| 359 | - blob_appendf(ob, "<pre><code>%.*s</code></pre>", n, z); | |
| 359 | + blob_appendf(ob, "<pre><code>%#h</code></pre>", n, z); | |
| 360 | 360 | }else{ |
| 361 | 361 | int k, j; |
| 362 | 362 | i++; |
| 363 | 363 | for(k=0; k<i && fossil_isspace(z[k]); k++){} |
| 364 | 364 | if( k==i ){ |
| 365 | - blob_appendf(ob, "<pre><code>%.*s</code></pre>", n-i, z+i); | |
| 365 | + blob_appendf(ob, "<pre><code>%#h</code></pre>", n-i, z+i); | |
| 366 | 366 | }else{ |
| 367 | 367 | for(j=k+1; j<i && !fossil_isspace(z[j]); j++){} |
| 368 | - blob_appendf(ob, "<pre><code class='language-%#h'>%.*s</code></pre>", | |
| 368 | + blob_appendf(ob, "<pre><code class='language-%#h'>%#h</code></pre>", | |
| 369 | 369 | j-k, z+k, n-i, z+i); |
| 370 | 370 | } |
| 371 | 371 | } |
| 372 | 372 | } |
| 373 | 373 | return 1; |
| 374 | 374 |
| --- src/markdown_html.c | |
| +++ src/markdown_html.c | |
| @@ -354,20 +354,20 @@ | |
| 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 |
| --- src/markdown_html.c | |
| +++ src/markdown_html.c | |
| @@ -354,20 +354,20 @@ | |
| 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>%#h</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>%#h</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'>%#h</code></pre>", |
| 369 | j-k, z+k, n-i, z+i); |
| 370 | } |
| 371 | } |
| 372 | } |
| 373 | return 1; |
| 374 |