Fossil SCM
Attempt to fix markdown rendering so that it correctly ignores table column separators that are contained without "code-span" back-ticks.
Commit
d6058989edb359cd0b801fc242863175cd4a9fbd38bd1e0a9e6e37440eceadfb
Parent
87e3ad31322d068…
1 file changed
+55
-25
+55
-25
| --- src/markdown.c | ||
| +++ src/markdown.c | ||
| @@ -466,10 +466,51 @@ | ||
| 466 | 466 | end = i; |
| 467 | 467 | } |
| 468 | 468 | } |
| 469 | 469 | } |
| 470 | 470 | |
| 471 | +/* | |
| 472 | +** data[*pI] should be a "`" character that introduces a code-span. | |
| 473 | +** The code-span boundry mark can be any number of one or more "`" | |
| 474 | +** characters. We do not know the size of the boundry marker, only | |
| 475 | +** that there is at least one "`" at data[*pI]. | |
| 476 | +** | |
| 477 | +** This routine increases *pI to move it past the code-span, including | |
| 478 | +** the closing boundary mark. Or, if the code-span is unterminated, | |
| 479 | +** this routine moves *pI past the opening boundary mark only. | |
| 480 | +*/ | |
| 481 | +static void skip_codespan(const char *data, size_t size, size_t *pI){ | |
| 482 | + size_t i = *pI; | |
| 483 | + size_t span_nb; /* Number of "`" characters in the boundary mark */ | |
| 484 | + size_t bt; | |
| 485 | + | |
| 486 | + assert( i<size ); | |
| 487 | + assert( data[i]=='`' ); | |
| 488 | + data += i; | |
| 489 | + size -= i; | |
| 490 | + | |
| 491 | + /* counting the number of opening backticks */ | |
| 492 | + i = 0; | |
| 493 | + span_nb = 0; | |
| 494 | + while( i<size && data[i]=='`' ){ | |
| 495 | + i++; | |
| 496 | + span_nb++; | |
| 497 | + } | |
| 498 | + if( i>=size ){ | |
| 499 | + *pI += span_nb; | |
| 500 | + return; | |
| 501 | + } | |
| 502 | + | |
| 503 | + /* finding the matching closing sequence */ | |
| 504 | + bt = 0; | |
| 505 | + while( i<size && bt<span_nb ){ | |
| 506 | + if( data[i]=='`' ) bt += 1; else bt = 0; | |
| 507 | + i++; | |
| 508 | + } | |
| 509 | + *pI += (bt == span_nb) ? i : span_nb; | |
| 510 | +} | |
| 511 | + | |
| 471 | 512 | |
| 472 | 513 | /* find_emph_char -- looks for the next emph char, skipping other constructs */ |
| 473 | 514 | static size_t find_emph_char(char *data, size_t size, char c){ |
| 474 | 515 | size_t i = 1; |
| 475 | 516 | |
| @@ -483,34 +524,13 @@ | ||
| 483 | 524 | continue; |
| 484 | 525 | } |
| 485 | 526 | |
| 486 | 527 | if( data[i]==c ) return i; |
| 487 | 528 | |
| 488 | - /* skipping a code span */ | |
| 489 | - if( data[i]=='`' ){ | |
| 490 | - size_t span_nb = 0, bt; | |
| 491 | - size_t tmp_i = 0; | |
| 492 | - | |
| 493 | - /* counting the number of opening backticks */ | |
| 494 | - while( i<size && data[i]=='`' ){ | |
| 495 | - i++; | |
| 496 | - span_nb++; | |
| 497 | - } | |
| 498 | - if( i>=size ) return 0; | |
| 499 | - | |
| 500 | - /* finding the matching closing sequence */ | |
| 501 | - bt = 0; | |
| 502 | - while( i<size && bt<span_nb ){ | |
| 503 | - if( !tmp_i && data[i]==c ) tmp_i = i; | |
| 504 | - if( data[i]=='`' ) bt += 1; else bt = 0; | |
| 505 | - i++; | |
| 506 | - } | |
| 507 | - if( i>=size ) return tmp_i; | |
| 508 | - i++; | |
| 509 | - | |
| 510 | - /* skipping a link */ | |
| 511 | - }else if( data[i]=='[' ){ | |
| 529 | + if( data[i]=='`' ){ /* skip a code span */ | |
| 530 | + skip_codespan(data, size, &i); | |
| 531 | + }else if( data[i]=='[' ){ /* skip a link */ | |
| 512 | 532 | size_t tmp_i = 0; |
| 513 | 533 | char cc; |
| 514 | 534 | i++; |
| 515 | 535 | while( i<size && data[i]!=']' ){ |
| 516 | 536 | if( !tmp_i && data[i]==c ) tmp_i = i; |
| @@ -1174,10 +1194,14 @@ | ||
| 1174 | 1194 | if( i<size && data[i]=='|') outer_sep++; |
| 1175 | 1195 | |
| 1176 | 1196 | /* count the number of pipes in the line */ |
| 1177 | 1197 | for(n_sep=0; i<size && data[i]!='\n'; i++){ |
| 1178 | 1198 | if( is_table_sep(data, i) ) n_sep++; |
| 1199 | + if( data[i]=='`' ){ | |
| 1200 | + skip_codespan(data, size, &i); | |
| 1201 | + i--; | |
| 1202 | + } | |
| 1179 | 1203 | } |
| 1180 | 1204 | |
| 1181 | 1205 | /* march back to check for optional last '|' before blanks and EOL */ |
| 1182 | 1206 | while( i && (data[i-1]==' ' || data[i-1]=='\t' || data[i-1]=='\n') ){ i--; } |
| 1183 | 1207 | if( i && is_table_sep(data, i-1) ) outer_sep += 1; |
| @@ -1834,11 +1858,17 @@ | ||
| 1834 | 1858 | /* skip blanks */ |
| 1835 | 1859 | while( i<size && (data[i]==' ' || data[i]=='\t') ){ i++; } |
| 1836 | 1860 | beg = i; |
| 1837 | 1861 | |
| 1838 | 1862 | /* forward to the next separator or EOL */ |
| 1839 | - while( i<size && !is_table_sep(data, i) && data[i]!='\n' ){ i++; } | |
| 1863 | + while( i<size && !is_table_sep(data, i) && data[i]!='\n' ){ | |
| 1864 | + if( data[i]=='`' ){ | |
| 1865 | + skip_codespan(data, size, &i); | |
| 1866 | + }else{ | |
| 1867 | + i++; | |
| 1868 | + } | |
| 1869 | + } | |
| 1840 | 1870 | end = i; |
| 1841 | 1871 | if( i<size ){ |
| 1842 | 1872 | i++; |
| 1843 | 1873 | if( data[i-1]=='\n' ) total = i; |
| 1844 | 1874 | } |
| 1845 | 1875 |
| --- src/markdown.c | |
| +++ src/markdown.c | |
| @@ -466,10 +466,51 @@ | |
| 466 | end = i; |
| 467 | } |
| 468 | } |
| 469 | } |
| 470 | |
| 471 | |
| 472 | /* find_emph_char -- looks for the next emph char, skipping other constructs */ |
| 473 | static size_t find_emph_char(char *data, size_t size, char c){ |
| 474 | size_t i = 1; |
| 475 | |
| @@ -483,34 +524,13 @@ | |
| 483 | continue; |
| 484 | } |
| 485 | |
| 486 | if( data[i]==c ) return i; |
| 487 | |
| 488 | /* skipping a code span */ |
| 489 | if( data[i]=='`' ){ |
| 490 | size_t span_nb = 0, bt; |
| 491 | size_t tmp_i = 0; |
| 492 | |
| 493 | /* counting the number of opening backticks */ |
| 494 | while( i<size && data[i]=='`' ){ |
| 495 | i++; |
| 496 | span_nb++; |
| 497 | } |
| 498 | if( i>=size ) return 0; |
| 499 | |
| 500 | /* finding the matching closing sequence */ |
| 501 | bt = 0; |
| 502 | while( i<size && bt<span_nb ){ |
| 503 | if( !tmp_i && data[i]==c ) tmp_i = i; |
| 504 | if( data[i]=='`' ) bt += 1; else bt = 0; |
| 505 | i++; |
| 506 | } |
| 507 | if( i>=size ) return tmp_i; |
| 508 | i++; |
| 509 | |
| 510 | /* skipping a link */ |
| 511 | }else if( data[i]=='[' ){ |
| 512 | size_t tmp_i = 0; |
| 513 | char cc; |
| 514 | i++; |
| 515 | while( i<size && data[i]!=']' ){ |
| 516 | if( !tmp_i && data[i]==c ) tmp_i = i; |
| @@ -1174,10 +1194,14 @@ | |
| 1174 | if( i<size && data[i]=='|') outer_sep++; |
| 1175 | |
| 1176 | /* count the number of pipes in the line */ |
| 1177 | for(n_sep=0; i<size && data[i]!='\n'; i++){ |
| 1178 | if( is_table_sep(data, i) ) n_sep++; |
| 1179 | } |
| 1180 | |
| 1181 | /* march back to check for optional last '|' before blanks and EOL */ |
| 1182 | while( i && (data[i-1]==' ' || data[i-1]=='\t' || data[i-1]=='\n') ){ i--; } |
| 1183 | if( i && is_table_sep(data, i-1) ) outer_sep += 1; |
| @@ -1834,11 +1858,17 @@ | |
| 1834 | /* skip blanks */ |
| 1835 | while( i<size && (data[i]==' ' || data[i]=='\t') ){ i++; } |
| 1836 | beg = i; |
| 1837 | |
| 1838 | /* forward to the next separator or EOL */ |
| 1839 | while( i<size && !is_table_sep(data, i) && data[i]!='\n' ){ i++; } |
| 1840 | end = i; |
| 1841 | if( i<size ){ |
| 1842 | i++; |
| 1843 | if( data[i-1]=='\n' ) total = i; |
| 1844 | } |
| 1845 |
| --- src/markdown.c | |
| +++ src/markdown.c | |
| @@ -466,10 +466,51 @@ | |
| 466 | end = i; |
| 467 | } |
| 468 | } |
| 469 | } |
| 470 | |
| 471 | /* |
| 472 | ** data[*pI] should be a "`" character that introduces a code-span. |
| 473 | ** The code-span boundry mark can be any number of one or more "`" |
| 474 | ** characters. We do not know the size of the boundry marker, only |
| 475 | ** that there is at least one "`" at data[*pI]. |
| 476 | ** |
| 477 | ** This routine increases *pI to move it past the code-span, including |
| 478 | ** the closing boundary mark. Or, if the code-span is unterminated, |
| 479 | ** this routine moves *pI past the opening boundary mark only. |
| 480 | */ |
| 481 | static void skip_codespan(const char *data, size_t size, size_t *pI){ |
| 482 | size_t i = *pI; |
| 483 | size_t span_nb; /* Number of "`" characters in the boundary mark */ |
| 484 | size_t bt; |
| 485 | |
| 486 | assert( i<size ); |
| 487 | assert( data[i]=='`' ); |
| 488 | data += i; |
| 489 | size -= i; |
| 490 | |
| 491 | /* counting the number of opening backticks */ |
| 492 | i = 0; |
| 493 | span_nb = 0; |
| 494 | while( i<size && data[i]=='`' ){ |
| 495 | i++; |
| 496 | span_nb++; |
| 497 | } |
| 498 | if( i>=size ){ |
| 499 | *pI += span_nb; |
| 500 | return; |
| 501 | } |
| 502 | |
| 503 | /* finding the matching closing sequence */ |
| 504 | bt = 0; |
| 505 | while( i<size && bt<span_nb ){ |
| 506 | if( data[i]=='`' ) bt += 1; else bt = 0; |
| 507 | i++; |
| 508 | } |
| 509 | *pI += (bt == span_nb) ? i : span_nb; |
| 510 | } |
| 511 | |
| 512 | |
| 513 | /* find_emph_char -- looks for the next emph char, skipping other constructs */ |
| 514 | static size_t find_emph_char(char *data, size_t size, char c){ |
| 515 | size_t i = 1; |
| 516 | |
| @@ -483,34 +524,13 @@ | |
| 524 | continue; |
| 525 | } |
| 526 | |
| 527 | if( data[i]==c ) return i; |
| 528 | |
| 529 | if( data[i]=='`' ){ /* skip a code span */ |
| 530 | skip_codespan(data, size, &i); |
| 531 | }else if( data[i]=='[' ){ /* skip a link */ |
| 532 | size_t tmp_i = 0; |
| 533 | char cc; |
| 534 | i++; |
| 535 | while( i<size && data[i]!=']' ){ |
| 536 | if( !tmp_i && data[i]==c ) tmp_i = i; |
| @@ -1174,10 +1194,14 @@ | |
| 1194 | if( i<size && data[i]=='|') outer_sep++; |
| 1195 | |
| 1196 | /* count the number of pipes in the line */ |
| 1197 | for(n_sep=0; i<size && data[i]!='\n'; i++){ |
| 1198 | if( is_table_sep(data, i) ) n_sep++; |
| 1199 | if( data[i]=='`' ){ |
| 1200 | skip_codespan(data, size, &i); |
| 1201 | i--; |
| 1202 | } |
| 1203 | } |
| 1204 | |
| 1205 | /* march back to check for optional last '|' before blanks and EOL */ |
| 1206 | while( i && (data[i-1]==' ' || data[i-1]=='\t' || data[i-1]=='\n') ){ i--; } |
| 1207 | if( i && is_table_sep(data, i-1) ) outer_sep += 1; |
| @@ -1834,11 +1858,17 @@ | |
| 1858 | /* skip blanks */ |
| 1859 | while( i<size && (data[i]==' ' || data[i]=='\t') ){ i++; } |
| 1860 | beg = i; |
| 1861 | |
| 1862 | /* forward to the next separator or EOL */ |
| 1863 | while( i<size && !is_table_sep(data, i) && data[i]!='\n' ){ |
| 1864 | if( data[i]=='`' ){ |
| 1865 | skip_codespan(data, size, &i); |
| 1866 | }else{ |
| 1867 | i++; |
| 1868 | } |
| 1869 | } |
| 1870 | end = i; |
| 1871 | if( i<size ){ |
| 1872 | i++; |
| 1873 | if( data[i-1]=='\n' ) total = i; |
| 1874 | } |
| 1875 |