Fossil SCM
Enable Pikchr in Fossil Wiki using markup of the form: <verbatim type="pikchr">...</verbatim>.
Commit
1fc2df905e74e1ebc77eec88bde5c5dd035551189ee5e021a364f5c28cd1fe98
Parent
c294f6bfe6f2eb6…
2 files changed
+2
-2
+63
-6
+2
-2
| --- src/markdown_html.c | ||
| +++ src/markdown_html.c | ||
| @@ -328,11 +328,11 @@ | ||
| 328 | 328 | |
| 329 | 329 | /* |
| 330 | 330 | ** The nSrc bytes at zSrc[] are Pikchr input text (allegedly). Process that |
| 331 | 331 | ** text and insert the result in place of the original. |
| 332 | 332 | */ |
| 333 | -static void fenced_code_pikchr_to_html( | |
| 333 | +void pikchr_to_html( | |
| 334 | 334 | Blob *ob, /* Write the generated SVG here */ |
| 335 | 335 | const char *zSrc, int nSrc, /* The Pikchr source text */ |
| 336 | 336 | const char *zArg, int nArg /* Addition arguments */ |
| 337 | 337 | ){ |
| 338 | 338 | int w = 0, h = 0; |
| @@ -412,11 +412,11 @@ | ||
| 412 | 412 | blob_appendf(ob, "<pre><code>%#h</code></pre>", n-i, z+i); |
| 413 | 413 | }else{ |
| 414 | 414 | for(j=k+1; j<i && !fossil_isspace(z[j]); j++){} |
| 415 | 415 | if( j-k==6 && strncmp(z+k,"pikchr",6)==0 ){ |
| 416 | 416 | while( j<i && fossil_isspace(z[j]) ){ j++; } |
| 417 | - fenced_code_pikchr_to_html(ob, z+i, n-i, z+j, i-j); | |
| 417 | + pikchr_to_html(ob, z+i, n-i, z+j, i-j); | |
| 418 | 418 | }else{ |
| 419 | 419 | blob_appendf(ob, "<pre><code class='language-%#h'>%#h</code></pre>", |
| 420 | 420 | j-k, z+k, n-i, z+i); |
| 421 | 421 | } |
| 422 | 422 | } |
| 423 | 423 |
| --- src/markdown_html.c | |
| +++ src/markdown_html.c | |
| @@ -328,11 +328,11 @@ | |
| 328 | |
| 329 | /* |
| 330 | ** The nSrc bytes at zSrc[] are Pikchr input text (allegedly). Process that |
| 331 | ** text and insert the result in place of the original. |
| 332 | */ |
| 333 | static void fenced_code_pikchr_to_html( |
| 334 | Blob *ob, /* Write the generated SVG here */ |
| 335 | const char *zSrc, int nSrc, /* The Pikchr source text */ |
| 336 | const char *zArg, int nArg /* Addition arguments */ |
| 337 | ){ |
| 338 | int w = 0, h = 0; |
| @@ -412,11 +412,11 @@ | |
| 412 | blob_appendf(ob, "<pre><code>%#h</code></pre>", n-i, z+i); |
| 413 | }else{ |
| 414 | for(j=k+1; j<i && !fossil_isspace(z[j]); j++){} |
| 415 | if( j-k==6 && strncmp(z+k,"pikchr",6)==0 ){ |
| 416 | while( j<i && fossil_isspace(z[j]) ){ j++; } |
| 417 | fenced_code_pikchr_to_html(ob, z+i, n-i, z+j, i-j); |
| 418 | }else{ |
| 419 | blob_appendf(ob, "<pre><code class='language-%#h'>%#h</code></pre>", |
| 420 | j-k, z+k, n-i, z+i); |
| 421 | } |
| 422 | } |
| 423 |
| --- src/markdown_html.c | |
| +++ src/markdown_html.c | |
| @@ -328,11 +328,11 @@ | |
| 328 | |
| 329 | /* |
| 330 | ** The nSrc bytes at zSrc[] are Pikchr input text (allegedly). Process that |
| 331 | ** text and insert the result in place of the original. |
| 332 | */ |
| 333 | void pikchr_to_html( |
| 334 | Blob *ob, /* Write the generated SVG here */ |
| 335 | const char *zSrc, int nSrc, /* The Pikchr source text */ |
| 336 | const char *zArg, int nArg /* Addition arguments */ |
| 337 | ){ |
| 338 | int w = 0, h = 0; |
| @@ -412,11 +412,11 @@ | |
| 412 | blob_appendf(ob, "<pre><code>%#h</code></pre>", n-i, z+i); |
| 413 | }else{ |
| 414 | for(j=k+1; j<i && !fossil_isspace(z[j]); j++){} |
| 415 | if( j-k==6 && strncmp(z+k,"pikchr",6)==0 ){ |
| 416 | while( j<i && fossil_isspace(z[j]) ){ j++; } |
| 417 | pikchr_to_html(ob, z+i, n-i, z+j, i-j); |
| 418 | }else{ |
| 419 | blob_appendf(ob, "<pre><code class='language-%#h'>%#h</code></pre>", |
| 420 | j-k, z+k, n-i, z+i); |
| 421 | } |
| 422 | } |
| 423 |
+63
-6
| --- src/wikiformat.c | ||
| +++ src/wikiformat.c | ||
| @@ -1358,10 +1358,60 @@ | ||
| 1358 | 1358 | if( p->zVerbatimId==0 ) return 1; |
| 1359 | 1359 | if( pMarkup->nAttr!=1 ) return 0; |
| 1360 | 1360 | z = pMarkup->aAttr[0].zValue; |
| 1361 | 1361 | return fossil_strcmp(z, p->zVerbatimId)==0; |
| 1362 | 1362 | } |
| 1363 | + | |
| 1364 | +/* | |
| 1365 | +** z[] points to the text that immediately follows markup of the form: | |
| 1366 | +** | |
| 1367 | +** <verbatim type='pikchr ...'> | |
| 1368 | +** | |
| 1369 | +** zClass is the argument to "type". This routine will process the | |
| 1370 | +** Pikchr text through the next matching </verbatim> (or until end-of-file) | |
| 1371 | +** and append the resulting SVG output onto p. It then returns the | |
| 1372 | +** number of bytes of text processed, including the closing </verbatim>. | |
| 1373 | +*/ | |
| 1374 | +static int wiki_process_pikchr(Renderer *p, char *z, const char *zClass){ | |
| 1375 | + ParsedMarkup m; /* Parsed closing tag */ | |
| 1376 | + int i = 0; /* For looping over z[] in search of </verbatim> */ | |
| 1377 | + int iRet = 0; /* Value to return */ | |
| 1378 | + int atEnd = 0; /* True if se have found the </verbatim> */ | |
| 1379 | + int nMarkup = 0; /* Length of a markup we are checking */ | |
| 1380 | + | |
| 1381 | + /* Search for the closing </verbatim> tag */ | |
| 1382 | + while( z[i]!=0 ){ | |
| 1383 | + char *zEnd = strchr(z+i, '<'); | |
| 1384 | + if( zEnd==0 ){ | |
| 1385 | + i += (int)strlen(z+i); | |
| 1386 | + iRet = i; | |
| 1387 | + break; | |
| 1388 | + } | |
| 1389 | + nMarkup = html_tag_length(zEnd); | |
| 1390 | + if( nMarkup<11 || fossil_strnicmp(zEnd, "</verbatim", 10)!=0 ){ | |
| 1391 | + i = (int)(zEnd - z) + 1; | |
| 1392 | + continue; | |
| 1393 | + } | |
| 1394 | + (void)parseMarkup(&m, z+i); | |
| 1395 | + atEnd = endVerbatim(p, &m); | |
| 1396 | + unparseMarkup(&m); | |
| 1397 | + if( atEnd ){ | |
| 1398 | + iRet = i + nMarkup; | |
| 1399 | + break; | |
| 1400 | + } | |
| 1401 | + i++; | |
| 1402 | + } | |
| 1403 | + | |
| 1404 | + /* The Pikchr source text should be i character in length and iRet is | |
| 1405 | + ** i plus the number of bytes in the </verbatim>. Generate the reply. | |
| 1406 | + */ | |
| 1407 | + assert( strncmp(zClass,"pikchr",6)==0 ); | |
| 1408 | + zClass += 6; | |
| 1409 | + while( fossil_isspace(zClass[0]) ) zClass++; | |
| 1410 | + pikchr_to_html(p->pOut, z, i, zClass, (int)strlen(zClass)); | |
| 1411 | + return iRet; | |
| 1412 | +} | |
| 1363 | 1413 | |
| 1364 | 1414 | /* |
| 1365 | 1415 | ** Return the MUTYPE for the top of the stack. |
| 1366 | 1416 | */ |
| 1367 | 1417 | static int stackTopType(Renderer *p){ |
| @@ -1658,30 +1708,37 @@ | ||
| 1658 | 1708 | /* Enter <verbatim> processing. With verbatim enabled, all other |
| 1659 | 1709 | ** markup other than the corresponding end-tag with the same ID is |
| 1660 | 1710 | ** ignored. |
| 1661 | 1711 | */ |
| 1662 | 1712 | if( markup.iCode==MARKUP_VERBATIM ){ |
| 1663 | - int ii, vAttrDidAppend=0; | |
| 1713 | + int ii; //, vAttrDidAppend=0; | |
| 1714 | + const char *zClass = 0; | |
| 1664 | 1715 | p->zVerbatimId = 0; |
| 1665 | 1716 | p->inVerbatim = 1; |
| 1666 | 1717 | p->preVerbState = p->state; |
| 1667 | 1718 | p->state &= ~ALLOW_WIKI; |
| 1668 | 1719 | for(ii=0; ii<markup.nAttr; ii++){ |
| 1669 | 1720 | if( markup.aAttr[ii].iACode == ATTR_ID ){ |
| 1670 | 1721 | p->zVerbatimId = markup.aAttr[ii].zValue; |
| 1671 | 1722 | }else if( markup.aAttr[ii].iACode==ATTR_TYPE ){ |
| 1672 | - blob_appendf(p->pOut, "<pre name='code' class='%s'>", | |
| 1673 | - markup.aAttr[ii].zValue); | |
| 1674 | - vAttrDidAppend=1; | |
| 1723 | + zClass = markup.aAttr[ii].zValue; | |
| 1675 | 1724 | }else if( markup.aAttr[ii].iACode==ATTR_LINKS |
| 1676 | 1725 | && !is_false(markup.aAttr[ii].zValue) ){ |
| 1677 | 1726 | p->state |= ALLOW_LINKS; |
| 1678 | 1727 | } |
| 1679 | 1728 | } |
| 1680 | - if( !vAttrDidAppend ) { | |
| 1681 | - endAutoParagraph(p); | |
| 1729 | + endAutoParagraph(p); | |
| 1730 | + if( zClass==0 ){ | |
| 1682 | 1731 | blob_append_string(p->pOut, "<pre class='verbatim'>"); |
| 1732 | + }else if( strncmp(zClass,"pikchr",6)==0 && | |
| 1733 | + (fossil_isspace(zClass[6]) || zClass[6]==0) ){ | |
| 1734 | + n += wiki_process_pikchr(p, z+n, zClass); | |
| 1735 | + p->inVerbatim = 0; | |
| 1736 | + p->state = p->preVerbState; | |
| 1737 | + }else{ | |
| 1738 | + blob_appendf(p->pOut, "<pre name='code' class='%h'>", | |
| 1739 | + zClass); | |
| 1683 | 1740 | } |
| 1684 | 1741 | p->wantAutoParagraph = 0; |
| 1685 | 1742 | }else |
| 1686 | 1743 | if( markup.iType==MUTYPE_LI ){ |
| 1687 | 1744 | if( backupToType(p, MUTYPE_LIST)==0 ){ |
| 1688 | 1745 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -1358,10 +1358,60 @@ | |
| 1358 | if( p->zVerbatimId==0 ) return 1; |
| 1359 | if( pMarkup->nAttr!=1 ) return 0; |
| 1360 | z = pMarkup->aAttr[0].zValue; |
| 1361 | return fossil_strcmp(z, p->zVerbatimId)==0; |
| 1362 | } |
| 1363 | |
| 1364 | /* |
| 1365 | ** Return the MUTYPE for the top of the stack. |
| 1366 | */ |
| 1367 | static int stackTopType(Renderer *p){ |
| @@ -1658,30 +1708,37 @@ | |
| 1658 | /* Enter <verbatim> processing. With verbatim enabled, all other |
| 1659 | ** markup other than the corresponding end-tag with the same ID is |
| 1660 | ** ignored. |
| 1661 | */ |
| 1662 | if( markup.iCode==MARKUP_VERBATIM ){ |
| 1663 | int ii, vAttrDidAppend=0; |
| 1664 | p->zVerbatimId = 0; |
| 1665 | p->inVerbatim = 1; |
| 1666 | p->preVerbState = p->state; |
| 1667 | p->state &= ~ALLOW_WIKI; |
| 1668 | for(ii=0; ii<markup.nAttr; ii++){ |
| 1669 | if( markup.aAttr[ii].iACode == ATTR_ID ){ |
| 1670 | p->zVerbatimId = markup.aAttr[ii].zValue; |
| 1671 | }else if( markup.aAttr[ii].iACode==ATTR_TYPE ){ |
| 1672 | blob_appendf(p->pOut, "<pre name='code' class='%s'>", |
| 1673 | markup.aAttr[ii].zValue); |
| 1674 | vAttrDidAppend=1; |
| 1675 | }else if( markup.aAttr[ii].iACode==ATTR_LINKS |
| 1676 | && !is_false(markup.aAttr[ii].zValue) ){ |
| 1677 | p->state |= ALLOW_LINKS; |
| 1678 | } |
| 1679 | } |
| 1680 | if( !vAttrDidAppend ) { |
| 1681 | endAutoParagraph(p); |
| 1682 | blob_append_string(p->pOut, "<pre class='verbatim'>"); |
| 1683 | } |
| 1684 | p->wantAutoParagraph = 0; |
| 1685 | }else |
| 1686 | if( markup.iType==MUTYPE_LI ){ |
| 1687 | if( backupToType(p, MUTYPE_LIST)==0 ){ |
| 1688 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -1358,10 +1358,60 @@ | |
| 1358 | if( p->zVerbatimId==0 ) return 1; |
| 1359 | if( pMarkup->nAttr!=1 ) return 0; |
| 1360 | z = pMarkup->aAttr[0].zValue; |
| 1361 | return fossil_strcmp(z, p->zVerbatimId)==0; |
| 1362 | } |
| 1363 | |
| 1364 | /* |
| 1365 | ** z[] points to the text that immediately follows markup of the form: |
| 1366 | ** |
| 1367 | ** <verbatim type='pikchr ...'> |
| 1368 | ** |
| 1369 | ** zClass is the argument to "type". This routine will process the |
| 1370 | ** Pikchr text through the next matching </verbatim> (or until end-of-file) |
| 1371 | ** and append the resulting SVG output onto p. It then returns the |
| 1372 | ** number of bytes of text processed, including the closing </verbatim>. |
| 1373 | */ |
| 1374 | static int wiki_process_pikchr(Renderer *p, char *z, const char *zClass){ |
| 1375 | ParsedMarkup m; /* Parsed closing tag */ |
| 1376 | int i = 0; /* For looping over z[] in search of </verbatim> */ |
| 1377 | int iRet = 0; /* Value to return */ |
| 1378 | int atEnd = 0; /* True if se have found the </verbatim> */ |
| 1379 | int nMarkup = 0; /* Length of a markup we are checking */ |
| 1380 | |
| 1381 | /* Search for the closing </verbatim> tag */ |
| 1382 | while( z[i]!=0 ){ |
| 1383 | char *zEnd = strchr(z+i, '<'); |
| 1384 | if( zEnd==0 ){ |
| 1385 | i += (int)strlen(z+i); |
| 1386 | iRet = i; |
| 1387 | break; |
| 1388 | } |
| 1389 | nMarkup = html_tag_length(zEnd); |
| 1390 | if( nMarkup<11 || fossil_strnicmp(zEnd, "</verbatim", 10)!=0 ){ |
| 1391 | i = (int)(zEnd - z) + 1; |
| 1392 | continue; |
| 1393 | } |
| 1394 | (void)parseMarkup(&m, z+i); |
| 1395 | atEnd = endVerbatim(p, &m); |
| 1396 | unparseMarkup(&m); |
| 1397 | if( atEnd ){ |
| 1398 | iRet = i + nMarkup; |
| 1399 | break; |
| 1400 | } |
| 1401 | i++; |
| 1402 | } |
| 1403 | |
| 1404 | /* The Pikchr source text should be i character in length and iRet is |
| 1405 | ** i plus the number of bytes in the </verbatim>. Generate the reply. |
| 1406 | */ |
| 1407 | assert( strncmp(zClass,"pikchr",6)==0 ); |
| 1408 | zClass += 6; |
| 1409 | while( fossil_isspace(zClass[0]) ) zClass++; |
| 1410 | pikchr_to_html(p->pOut, z, i, zClass, (int)strlen(zClass)); |
| 1411 | return iRet; |
| 1412 | } |
| 1413 | |
| 1414 | /* |
| 1415 | ** Return the MUTYPE for the top of the stack. |
| 1416 | */ |
| 1417 | static int stackTopType(Renderer *p){ |
| @@ -1658,30 +1708,37 @@ | |
| 1708 | /* Enter <verbatim> processing. With verbatim enabled, all other |
| 1709 | ** markup other than the corresponding end-tag with the same ID is |
| 1710 | ** ignored. |
| 1711 | */ |
| 1712 | if( markup.iCode==MARKUP_VERBATIM ){ |
| 1713 | int ii; //, vAttrDidAppend=0; |
| 1714 | const char *zClass = 0; |
| 1715 | p->zVerbatimId = 0; |
| 1716 | p->inVerbatim = 1; |
| 1717 | p->preVerbState = p->state; |
| 1718 | p->state &= ~ALLOW_WIKI; |
| 1719 | for(ii=0; ii<markup.nAttr; ii++){ |
| 1720 | if( markup.aAttr[ii].iACode == ATTR_ID ){ |
| 1721 | p->zVerbatimId = markup.aAttr[ii].zValue; |
| 1722 | }else if( markup.aAttr[ii].iACode==ATTR_TYPE ){ |
| 1723 | zClass = markup.aAttr[ii].zValue; |
| 1724 | }else if( markup.aAttr[ii].iACode==ATTR_LINKS |
| 1725 | && !is_false(markup.aAttr[ii].zValue) ){ |
| 1726 | p->state |= ALLOW_LINKS; |
| 1727 | } |
| 1728 | } |
| 1729 | endAutoParagraph(p); |
| 1730 | if( zClass==0 ){ |
| 1731 | blob_append_string(p->pOut, "<pre class='verbatim'>"); |
| 1732 | }else if( strncmp(zClass,"pikchr",6)==0 && |
| 1733 | (fossil_isspace(zClass[6]) || zClass[6]==0) ){ |
| 1734 | n += wiki_process_pikchr(p, z+n, zClass); |
| 1735 | p->inVerbatim = 0; |
| 1736 | p->state = p->preVerbState; |
| 1737 | }else{ |
| 1738 | blob_appendf(p->pOut, "<pre name='code' class='%h'>", |
| 1739 | zClass); |
| 1740 | } |
| 1741 | p->wantAutoParagraph = 0; |
| 1742 | }else |
| 1743 | if( markup.iType==MUTYPE_LI ){ |
| 1744 | if( backupToType(p, MUTYPE_LIST)==0 ){ |
| 1745 |