Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Minor refactoring. Move the definition of BLOB_APPEND_LITERAL()
macro from markdown_html.c to blob.c so that
it could be used outside of markdown_html.c .
Also rename it to lowercase for consistency with other API.
Within markdown.c use that newly available macro instead of
blob_append_string() .
Within markdown_html.c use it for footnotes-relevant code.
Other invocations of BLOB_APPEND_LITERAL() within
markdown_html.c are left intact (they use an alias) in order to
simplify the potential merge with the trunk.
|
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | markdown-footnotes |
Files: | files | file ages | folders |
SHA3-256: |
c8a8d0c94cf5f055f5242d0d7b61b642 |
User & Date: | george 2022-02-23 09:45:17 |
Context
2022-02-23
| ||
12:33 | Count overnesting as the fourth type of the footnote-related issues and report accordingly. ... (check-in: ae297bb6 user: george tags: markdown-footnotes) | |
09:45 |
Minor refactoring. Move the definition of BLOB_APPEND_LITERAL()
macro from markdown_html.c to blob.c so that
it could be used outside of markdown_html.c .
Also rename it to lowercase for consistency with other API.
Within markdown.c use that newly available macro instead of
blob_append_string() .
Within markdown_html.c use it for footnotes-relevant code.
Other invocations of BLOB_APPEND_LITERAL() within
markdown_html.c are left intact (they use an alias) in order to
simplify the potential merge with the trunk.
...
(check-in: c8a8d0c9 user: george tags: markdown-footnotes)
| |
08:21 |
Minor refactoring. Move the definition of BLOB_APPEND_BLOB()
macro from markdown_html.c to blob.c so that
it could be used outside of markdown_html.c .
Also rename it to blob_appendb() for consistency with
blob_appendf() and other API.
Within markdown.c use that newly available macro where appropriate.
Within markdown_html.c use it for footnotes-relevant code.
Other invocations of BLOB_APPEND_BLOB() within
markdown_html.c are left intact (they use an alias) in order to
simplify the potential merge with the trunk.
...
(check-in: 33a681eb user: george tags: markdown-footnotes)
| |
Changes
Changes to src/blob.c.
︙ | ︙ | |||
57 58 59 60 61 62 63 64 65 66 67 68 69 70 | /* ** Append blob contents to another */ #define blob_appendb(dest, src) \ blob_append((dest), blob_buffer(src), blob_size(src)) /* ** Seek whence parameter values */ #define BLOB_SEEK_SET 1 #define BLOB_SEEK_CUR 2 #endif /* INTERFACE */ | > > > > > > > > > > > > > > > > > | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | /* ** Append blob contents to another */ #define blob_appendb(dest, src) \ blob_append((dest), blob_buffer(src), blob_size(src)) /* ** Append a string literal to a blob ** TODO: Consider renaming to blob_appendl() */ #define blob_append_literal(blob, literal) \ blob_append((blob), "" literal, (sizeof literal)-1) /* * The empty string in the second argument leads to a syntax error * when the macro is not used with a string literal. Unfortunately * the error is not overly explicit. */ /* ** TODO: Suggested for removal because the name seems misleading. */ #define blob_append_string blob_append_literal /* ** Seek whence parameter values */ #define BLOB_SEEK_SET 1 #define BLOB_SEEK_CUR 2 #endif /* INTERFACE */ |
︙ | ︙ | |||
329 330 331 332 333 334 335 | } nUsed = pBlob->nUsed; pBlob->nUsed += nData; pBlob->aData[pBlob->nUsed] = 0; memcpy(&pBlob->aData[nUsed], aData, nData); } | < < < < < < < | 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | } nUsed = pBlob->nUsed; pBlob->nUsed += nData; pBlob->aData[pBlob->nUsed] = 0; memcpy(&pBlob->aData[nUsed], aData, nData); } /* ** Append a single character to the blob. If pBlob is zero then the ** character is written directly to stdout. */ void blob_append_char(Blob *pBlob, char c){ if( pBlob==0 || pBlob->nUsed+1 >= pBlob->nAlloc ){ blob_append_full(pBlob, &c, 1); |
︙ | ︙ |
Changes to src/markdown.c.
︙ | ︙ | |||
2685 2686 2687 2688 2689 2690 2691 | j++; nDups++; } if( i+1<j ){ Blob list = empty_blob; blob_reserve(&list, k); /* must match _joined_footnote_indicator in html_footnote_item() */ | | | | | | 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 | j++; nDups++; } if( i+1<j ){ Blob list = empty_blob; blob_reserve(&list, k); /* must match _joined_footnote_indicator in html_footnote_item() */ blob_append_literal(&list, "<ul class='fn-joined'>\n"); for(k=i; k<j; k++){ struct footnote *y = fn + k; blob_append_literal(&list, "<li>"); if( blob_size(&y->upc) ){ blob_appendb(&list, &y->upc); blob_reset(&y->upc); } blob_appendb(&list, &y->text); blob_append_literal(&list, "</li>\n"); /* free memory buffer */ blob_reset(&y->text); if( k!=i ) blob_reset(&y->id); } blob_append_literal(&list, "</ul>\n"); x->text = list; g.ftntsIssues[2]++; } i = j; } if( nDups ){ /* clean rndr.notes.all from invalidated footnotes */ const int n = rndr.notes.nLbled - nDups; |
︙ | ︙ |
Changes to src/markdown_html.c.
︙ | ︙ | |||
48 49 50 51 52 53 54 | }; /* INTER_BLOCK -- skip a line between block level elements */ #define INTER_BLOCK(ob) \ do { if( blob_size(ob)>0 ) blob_append_char(ob, '\n'); } while (0) | | < | < < < < | > | | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | }; /* INTER_BLOCK -- skip a line between block level elements */ #define INTER_BLOCK(ob) \ do { if( blob_size(ob)>0 ) blob_append_char(ob, '\n'); } while (0) /* BLOB_APPEND_LITERAL -- append a string literal to a blob ** TODO: Refactor all invocations to use global macro blob_append_literal() */ #define BLOB_APPEND_LITERAL blob_append_literal /* BLOB_APPEND_BLOB -- append blob contents to another ** TODO: Refactor all invocations to use global macro blob_appendb() */ #define BLOB_APPEND_BLOB(dest, src) blob_appendb((dest), (src)) #ifndef FOOTNOTES_WITHOUT_URI #define BLOB_APPEND_URI(dest,ctx) blob_appendb(dest,&((ctx)->reqURI)) #else #define BLOB_APPEND_URI(dest,ctx) |
︙ | ︙ | |||
348 349 350 351 352 353 354 | ){ const char *z = blob_buffer(upc); int i, n = blob_size(upc); if( n<3 ) return; assert( z[0]=='.' && z[n-1] == ':' ); if( bHTML ){ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 | ){ const char *z = blob_buffer(upc); int i, n = blob_size(upc); if( n<3 ) return; assert( z[0]=='.' && z[n-1] == ':' ); if( bHTML ){ blob_append_literal(ob, "<span class='fn-upc'>" "<span class='fn-upcDot'>.</span>"); } n = 0; do{ z++; if( *z!='.' && *z!=':' ){ assert( fossil_isalnum(*z) || *z=='-' ); n++; continue; } assert( n ); if( bHTML ) blob_append_literal(ob, "<span class='"); blob_append_literal(ob, "fn-upc-"); for(i=-n; i<0; i++){ blob_append_char(ob, fossil_tolower(z[i]) ); } if( bHTML ){ blob_append_literal(ob, "'>"); blob_append(ob, z-n, n); blob_append_literal(ob, "</span>"); }else{ blob_append_char(ob, ' '); } n = 0; if( bHTML ){ if( *z==':' ){ blob_append_literal(ob,"<span class='fn-upcColon'>:</span>"); }else{ blob_append_literal(ob,"<span class='fn-upcDot'>.</span>"); } } }while( *z != ':' ); if( bHTML ) blob_append_literal(ob,"</span>\n"); } static int html_footnote_ref( struct Blob *ob, const struct Blob *span, const struct Blob *upc, int iMark, int locus, void *opaque ){ const struct MarkdownToHtml* ctx = (struct MarkdownToHtml*)opaque; const bitfield64_t l = to_base26(locus-1,0); char pos[32]; memset(pos,0,32); assert( locus > 0 ); /* expect BUGs if the following yields compiler warnings */ if( iMark > 0 ){ /* a regular reference to a footnote */ sprintf(pos, "%s-%i-%s", ctx->unique.c, iMark, l.c); if(span && blob_size(span)) { blob_append_literal(ob,"<span class='"); append_footnote_upc(ob, upc, 0); blob_append_literal(ob,"notescope' id='noteref"); blob_appendf(ob,"%s'>",pos); blob_appendb(ob, span); blob_trim(ob); blob_append_literal(ob,"<sup class='noteref'><a href='"); BLOB_APPEND_URI(ob, ctx); blob_appendf(ob,"#footnote%s'>%i</a></sup></span>", pos, iMark); }else{ blob_trim(ob); blob_append_literal(ob,"<sup class='"); append_footnote_upc(ob, upc, 0); blob_append_literal(ob,"noteref'><a href='"); BLOB_APPEND_URI(ob, ctx); blob_appendf(ob,"#footnote%s' id='noteref%s'>%i</a></sup>", pos, pos, iMark); } }else{ /* misreference */ assert( iMark == -1 ); sprintf(pos, "%s-%s", ctx->unique.c, l.c); if(span && blob_size(span)) { blob_appendf(ob, "<span class='notescope' id='misref%s'>", pos); blob_appendb(ob, span); blob_trim(ob); blob_append_literal(ob, "<sup class='noteref misref'><a href='"); BLOB_APPEND_URI(ob, ctx); blob_appendf(ob, "#misreference%s'>misref</a></sup></span>", pos); }else{ blob_trim(ob); blob_append_literal(ob, "<sup class='noteref misref'><a href='"); BLOB_APPEND_URI(ob, ctx); blob_appendf(ob, "#misreference%s' id='misref%s'>", pos, pos); blob_append_literal(ob, "misref</a></sup>"); } } return 1; } /* Render a single item of the footnotes list. * Each backref gets a unique id to enable dynamic styling. */ static void html_footnote_item( struct Blob *ob, const struct Blob *text, int iMark, int nUsed, void *opaque ){ const struct MarkdownToHtml* ctx = (struct MarkdownToHtml*)opaque; const char * const unique = ctx->unique.c; /* make.footnote_item() invocations should pass args accordingly */ const struct Blob *upc = text+1; assert( nUsed >= 0 ); /* expect BUGs if the following yields compiler warnings */ if( iMark < 0 ){ /* misreferences */ assert( iMark == -1 ); assert( nUsed ); blob_append_literal(ob,"<li class='fn-misreference'>" "<sup class='fn-backrefs'>"); if( nUsed == 1 ){ blob_appendf(ob,"<a id='misreference%s-a' href='", unique); BLOB_APPEND_URI(ob, ctx); blob_appendf(ob,"#misref%s-a'>^</a>", unique); }else{ int i; blob_append_char(ob, '^'); for(i=0; i<nUsed && i<26; i++){ const int c = i + (unsigned)'a'; blob_appendf(ob," <a id='misreference%s-%c' href='", unique,c); BLOB_APPEND_URI(ob, ctx); blob_appendf(ob,"#misref%s-%c'>%c</a>", unique,c, c); } if( i < nUsed ) blob_append_literal(ob," …"); } blob_append_literal(ob,"</sup>\n<span>Misreference</span>"); }else if( iMark > 0 ){ /* regular, joined and overnested footnotes */ char pos[24]; int bJoin = 0; #define _joined_footnote_indicator "<ul class='fn-joined'>" #define _jfi_sz (sizeof(_joined_footnote_indicator)-1) assert( text ); assert( blob_size(text) ); memset(pos,0,24); sprintf(pos, "%s-%i", unique, iMark); blob_appendf(ob, "<li id='footnote%s' class='", pos); if( nUsed ){ if( blob_size(text)>=_jfi_sz && !memcmp(blob_buffer(text),_joined_footnote_indicator,_jfi_sz)){ bJoin = 1; blob_append_literal(ob, "fn-joined "); } append_footnote_upc(ob, upc, 0); }else{ blob_append_literal(ob, "fn-toodeep "); } if( nUsed <= 1 ){ blob_append_literal(ob, "fn-monoref'><sup class='fn-backrefs'>"); blob_appendf(ob,"<a id='footnote%s-a' href='", pos); BLOB_APPEND_URI(ob, ctx); blob_appendf(ob,"#noteref%s-a'>^</a>", pos); }else{ int i; blob_append_literal(ob, "fn-polyref'><sup class='fn-backrefs'>^"); for(i=0; i<nUsed && i<26; i++){ const int c = i + (unsigned)'a'; blob_appendf(ob," <a id='footnote%s-%c' href='", pos,c); BLOB_APPEND_URI(ob, ctx); blob_appendf(ob,"#noteref%s-%c'>%c</a>", pos,c, c); } /* It's unlikely that so many backrefs will be usefull */ /* but maybe for some machine generated documents... */ for(; i<nUsed && i<676; i++){ const bitfield64_t l = to_base26(i,0); blob_appendf(ob," <a id='footnote%s-%s' href='", pos, l.c); BLOB_APPEND_URI(ob, ctx); blob_appendf(ob,"#noteref%s-%s'>%s</a>", pos,l.c, l.c); } if( i < nUsed ) blob_append_literal(ob," …"); } blob_append_literal(ob,"</sup>\n"); if( bJoin ){ blob_append_literal(ob,"<sup class='fn-joined'></sup><ul>"); blob_append(ob,blob_buffer(text)+_jfi_sz,blob_size(text)-_jfi_sz); }else if( nUsed ){ append_footnote_upc(ob, upc, 1); blob_appendb(ob, text); }else{ blob_append_literal(ob,"<i></i>\n" "<pre><code class='language-markdown'>"); if( blob_size(upc) ){ blob_appendb(ob, upc); } html_escape(ob, blob_buffer(text), blob_size(text)); blob_append_literal(ob,"</code></pre>"); } #undef _joined_footnote_indicator #undef _jfi_sz }else{ /* a footnote was defined but wasn't referenced */ /* make.footnote_item() invocations should pass args accordingly */ const struct Blob * id = text-1; assert( !nUsed ); assert( text ); assert( blob_size(text) ); assert( blob_size(id) ); blob_append_literal(ob,"<li class='fn-unreferenced'>\n[^ <code>"); html_escape(ob, blob_buffer(id), blob_size(id)); blob_append_literal(ob, "</code> ]<i></i>\n" "<pre><code class='language-markdown'>"); if( blob_size(upc) ){ blob_appendb(ob, upc); } html_escape(ob, blob_buffer(text), blob_size(text)); blob_append_literal(ob,"</code></pre>"); } blob_append_literal(ob, "\n</li>\n"); } static void html_footnotes( struct Blob *ob, const struct Blob *items, void *opaque ){ if( items && blob_size(items) ){ blob_append_literal(ob, "\n<hr class='footnotes-separator'/>\n<ol class='footnotes'>\n"); blob_appendb(ob, items); blob_append_literal(ob, "</ol>\n"); } } /* HTML span tags */ static int html_raw_html_tag(struct Blob *ob, struct Blob *text, void *opaque){ blob_append(ob, blob_buffer(text), blob_size(text)); |
︙ | ︙ |