Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Handle misreferences: a reference to undefined footnote. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | markdown-footnotes |
Files: | files | file ages | folders |
SHA3-256: |
28e6a9cd1355bb58d8644842e3906cbb |
User & Date: | george 2022-02-04 23:07:54 |
Context
2022-02-06
| ||
22:53 | Handle misreferences more thoroughly. Implement support of footnotes-within-footnotes with (hopefully) proper crosslinking (that's where it's getting tricky). ... (check-in: 1787f6df user: george tags: markdown-footnotes) | |
2022-02-04
| ||
23:07 | Handle misreferences: a reference to undefined footnote. ... (check-in: 28e6a9cd user: george tags: markdown-footnotes) | |
19:47 | Minor code refactoring. ... (check-in: 2636e224 user: george tags: markdown-footnotes) | |
Changes
Changes to src/default.css.
︙ | ︙ | |||
1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 | font-weight: bold; } div.markdown > ol.footnotes > li > .footnote-backrefs > a:target { background: gold; } div.markdown sup > a.noteref:target { background: gold; } div.markdown span.notescope:hover, div.markdown span.notescope:target { border-bottom: 2px solid gold; } div.markdown span.notescope:hover > sup > a.noteref, div.markdown span.notescope:target > sup > a.noteref { | > > > > | 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 | font-weight: bold; } div.markdown > ol.footnotes > li > .footnote-backrefs > a:target { background: gold; } div.markdown sup > a.noteref:target { background: gold; } div.markdown sup.misref { color: red; font-size: 90%; } div.markdown span.notescope:hover, div.markdown span.notescope:target { border-bottom: 2px solid gold; } div.markdown span.notescope:hover > sup > a.noteref, div.markdown span.notescope:target > sup > a.noteref { |
︙ | ︙ |
Changes to src/markdown.c.
︙ | ︙ | |||
172 173 174 175 176 177 178 | int iDepth; /* Depth of recursion */ int nBlobCache; /* Number of entries in aBlobCache */ struct Blob *aBlobCache[20]; /* Cache of Blobs available for reuse */ struct { Blob all; /* array of footnotes */ int nLbled; /* number of labeled footnotes found during the first pass */ | | > > | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | int iDepth; /* Depth of recursion */ int nBlobCache; /* Number of entries in aBlobCache */ struct Blob *aBlobCache[20]; /* Cache of Blobs available for reuse */ struct { Blob all; /* array of footnotes */ int nLbled; /* number of labeled footnotes found during the first pass */ int nMarks; /* counts distinct indices found during the second pass */ struct footnote missing; /* a dummy footnote, its negative index counts missing refs */ } notes; }; /* html_tag -- structure for quick HTML tag search (inspired from discount) */ struct html_tag { const char *text; int size; |
︙ | ︙ | |||
206 207 208 209 210 211 212 213 214 215 216 217 218 219 | /*************************** * STATIC HELPER FUNCTIONS * ***************************/ /* build_ref_id -- collapse whitespace from input text to make it a ref id */ static int build_ref_id(struct Blob *id, const char *data, size_t size){ size_t beg, i; char *id_data; /* skip leading whitespace */ while( size>0 && (data[0]==' ' || data[0]=='\t' || data[0]=='\n') ){ data++; | > | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | /*************************** * STATIC HELPER FUNCTIONS * ***************************/ /* build_ref_id -- collapse whitespace from input text to make it a ref id */ /* FIXME: does this function handle non-Unix newlines? */ static int build_ref_id(struct Blob *id, const char *data, size_t size){ size_t beg, i; char *id_data; /* skip leading whitespace */ while( size>0 && (data[0]==' ' || data[0]=='\t' || data[0]=='\n') ){ data++; |
︙ | ︙ | |||
1219 1220 1221 1222 1223 1224 1225 | id_data++; id_size--; } } if( bFootnote ){ fn = get_footnote(rndr, id_data, id_size); | | > > > | > > > | 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 | id_data++; id_size--; } } if( bFootnote ){ fn = get_footnote(rndr, id_data, id_size); if( !fn ) { rndr->notes.missing.index--; fn = &rndr->notes.missing; } }else if( get_link_ref(rndr, link, title, id_data, id_size)<0 ){ goto char_link_cleanup; } i = id_end+1; /* shortcut reference style link or free-standing footnote refernece */ }else{ if(!is_img && size>3 && data[1]=='^'){ /* free-standing footnote reference */ fn = get_footnote(rndr, data+2, txt_e-2); if( !fn ) { rndr->notes.missing.index--; fn = &rndr->notes.missing; } release_work_buffer(rndr, content); content = 0; }else if( get_link_ref(rndr, link, title, data+1, txt_e-1)<0 ){ goto char_link_cleanup; } /* rewinding a closing square bracket */ |
︙ | ︙ | |||
2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 | if( !rndrer ) return; rndr.make = *rndrer; rndr.nBlobCache = 0; rndr.iDepth = 0; rndr.refs = empty_blob; rndr.notes.all = empty_blob; rndr.notes.nMarks = 0; for(i=0; i<256; i++) rndr.active_char[i] = 0; if( (rndr.make.emphasis || rndr.make.double_emphasis || rndr.make.triple_emphasis) && rndr.make.emph_chars ){ for(i=0; rndr.make.emph_chars[i]; i++){ | > > > > > | 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 | if( !rndrer ) return; rndr.make = *rndrer; rndr.nBlobCache = 0; rndr.iDepth = 0; rndr.refs = empty_blob; rndr.notes.all = empty_blob; rndr.notes.nMarks = 0; rndr.notes.missing.id = empty_blob; rndr.notes.missing.text = empty_blob; rndr.notes.missing.index = 0; rndr.notes.missing.nUsed = 0; for(i=0; i<256; i++) rndr.active_char[i] = 0; if( (rndr.make.emphasis || rndr.make.double_emphasis || rndr.make.triple_emphasis) && rndr.make.emph_chars ){ for(i=0; rndr.make.emph_chars[i]; i++){ |
︙ | ︙ |
Changes to src/markdown_html.c.
︙ | ︙ | |||
326 327 328 329 330 331 332 | BLOB_APPEND_LITERAL(ob, " </tr>\n"); } static int html_footnote_ref( struct Blob *ob, const struct Blob *span, int index, int locus, void *opaque ){ const struct MarkdownToHtml *ctx = (struct MarkdownToHtml*)opaque; | > > > | | < < | | > | | | | | | | | | | | | > > > > > > > > > > > > > | 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 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 | BLOB_APPEND_LITERAL(ob, " </tr>\n"); } static int html_footnote_ref( struct Blob *ob, const struct Blob *span, int index, int locus, void *opaque ){ const struct MarkdownToHtml *ctx = (struct MarkdownToHtml*)opaque; /* expect BUGs if the following yields compiler warnings */ if( index>0 && locus>0 ){ const bitfield64_t l = to_base26(locus-1,0); char pos[32]; memset(pos,0,32); sprintf(pos, "%s-%i-%s", ctx->unique.c, index, l.c); if(span && blob_size(span)) { BLOB_APPEND_LITERAL(ob,"<span class='notescope' id='noteref"); blob_appendf(ob,"%s'>",pos); BLOB_APPEND_BLOB(ob, span); blob_trim(ob); BLOB_APPEND_LITERAL(ob,"<sup><a class='noteref' href='#footnote"); blob_appendf(ob,"%s'>%i</a></sup></span>", pos, index); }else{ blob_trim(ob); BLOB_APPEND_LITERAL(ob,"<sup><a class='noteref' href='#footnote"); blob_appendf(ob,"%s' id='noteref%s'>%i</a></sup>", pos, pos, index); } }else if(span && blob_size(span)) { BLOB_APPEND_LITERAL(ob, "<span class='notescope' id='misref"); blob_appendf(ob, "%s-%i'>", ctx->unique.c, -index); BLOB_APPEND_BLOB(ob, span); blob_trim(ob); BLOB_APPEND_LITERAL(ob, "<sup class='misref'>misreference</sup></span>"); }else{ blob_trim(ob); BLOB_APPEND_LITERAL(ob, "<sup class='misref' id='misref"); blob_appendf(ob, "%s-%i", ctx->unique.c, -index); BLOB_APPEND_LITERAL(ob, "'>misreference</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( |
︙ | ︙ |
Changes to test/markdown-test3.md.
1 2 3 4 | Markdown Footnotes Test Document ================================ | | | > > | > > > > | | > | > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | Markdown Footnotes Test Document ================================ **This document** should help with testing of footnotes support that is introduced by the ["`markdown-footnotes`"][branch] branch. It **might look pretty misformatted unless rendered by the proper Fossil executable that incorporates the abovementioned branch.**[^1] Developers are invited to add test cases here[^here]. It is suggested that the more simple is a test case the earlier it should appear in this document.[^ if glitch occurs ] A footnote's label should be case insensitive[^ case INSENSITIVE ], it is whitespace-savvy and can even contain newlines.[^ a multiline label] A labeled footnote may be [referenced several times][^many-refs]. A footnote's text should support Markdown [markup][^]. Another reference[^many-refs] to the preveously used footnote. Inline footnotes are supported.(^These may be usefull for adding <s>small</s> comments.) If [undefined label is used][^] then red "`misreference`" is emited instead of a numeric marker.[^ see it yourself ] This can be overridden by the skin though. ## Footnotes [branch]: /timeline?r=markdown-footnotes&nowiki [^ 1]: Footnotes is a Fossil' extention of Markdown. Your other tools may have limited support for these. [^here]: [History of test/markdown-test3.md](/finfo/test/markdown-test3.md) [^if glitch occurs]: So that simple cases are processed even if a glitch happens for more tricky cases. [^ CASE insensitive ]: And also tolerate whitespaces. [^ a multiline label ]: But at a footnote's definition it should still be written within square brackets on a single line. [^many-refs]: Each letter on the left is a back-reference to the place of use. Highlighted back-reference indicates a place from which navigation occurred. [^markup]: E.g. *emphasis*, and [so on](/md_rules). [^undefined label is used]: For example due to a typo. |