Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Clean-up and rephrase some comments. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | markdown-footnotes |
Files: | files | file ages | folders |
SHA3-256: |
a62c876896ae11002ba464a71fc92ef9 |
User & Date: | george 2022-02-17 00:17:28 |
Context
2022-02-17
| ||
22:09 | If a footnote's text starts with a token of the special form then use this token to derive a set of CSS classes that are added to that footnote and its references. This enables users to style elements of a particular footnote provided that the administrator provisioned and documented some special CSS classes in a custum skin. Default skin does not provide any of such special classes which makes this feature an "opt-in". ... (check-in: 92516ced user: george tags: markdown-footnotes) | |
00:17 | Clean-up and rephrase some comments. ... (check-in: a62c8768 user: george tags: markdown-footnotes) | |
2022-02-16
| ||
23:08 | Make parsing slightly faster and fix a comment. No changes in functionality. ... (check-in: a36dd09d user: george tags: markdown-footnotes) | |
Changes
Changes to src/markdown.c.
︙ | ︙ | |||
211 212 213 214 215 216 217 | }; /*************************** * STATIC HELPER FUNCTIONS * ***************************/ /* build_ref_id -- collapse whitespace from input text to make it a ref id */ | | | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | }; /*************************** * STATIC HELPER FUNCTIONS * ***************************/ /* build_ref_id -- collapse whitespace from input text to make it a ref id */ /* TODO: maybe also handle CR+LF line endings? */ 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++; |
︙ | ︙ | |||
282 283 284 285 286 287 288 | const int szA = blob_size(&a->id), szB = blob_size(&b->id); if( szA ){ if( szB ){ int cmp = blob_compare(&a->id, &b->id); if( cmp ) return cmp; }else return -1; }else return szB ? 1 : 0; | | > | 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | const int szA = blob_size(&a->id), szB = blob_size(&b->id); if( szA ){ if( szB ){ int cmp = blob_compare(&a->id, &b->id); if( cmp ) return cmp; }else return -1; }else return szB ? 1 : 0; /* IDs are equal and non-empty */ if( a->defno < b->defno ) return -1; if( a->defno > b->defno ) return 1; assert(!"reachable"); return 0; /* should never reach here */ } /* cmp_footnote_sort -- comparison function for footnotes qsort. * Unreferenced footnotes (when nUsed == 0) sort last and * are sorted in the order of definition in the source */ static int cmp_footnote_sort(const void *fna, const void *fnb){ |
︙ | ︙ | |||
1120 1121 1122 1123 1124 1125 1126 | blob_append(&fn.text, text, size); blob_append(&rndr->notes.all, (char *)&fn, sizeof fn); return (struct footnote*)( blob_buffer(&rndr->notes.all) +( blob_size(&rndr->notes.all)-sizeof fn )); } /* Return the offset of the matching closing bracket or 0 if not found. | | > > > > > | | | 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 | blob_append(&fn.text, text, size); blob_append(&rndr->notes.all, (char *)&fn, sizeof fn); return (struct footnote*)( blob_buffer(&rndr->notes.all) +( blob_size(&rndr->notes.all)-sizeof fn )); } /* Return the offset of the matching closing bracket or 0 if not found. ** begin[0] must be either '[' or '(' ** ** TODO: It seems that things like "\\(" are not handled correctly. ** That is historical behavior for a corner-case, ** so it's left as it is until somebody complains. */ static inline size_t matching_bracket_offset( const char* begin, const char* end ){ const char *i; int level; const char bra = *begin; const char ket = bra=='[' ? ']' : ')'; assert( bra=='[' || bra=='(' ); for(i=begin+1,level=1; i!=end; i++){ if( *i=='\n' ) /* do nothing */; else if( i[-1]=='\\' ) continue; else if( *i==bra ) level++; else if( *i==ket ){ if( --level<=0 ) return i-begin; } } return 0; } |
︙ | ︙ | |||
2308 2309 2310 2311 2312 2313 2314 | && data[i]!=' ' && data[i]!='\t' && data[i]!='\n' && data[i]!='\r' ){ i += 1; } | | | 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 | && data[i]!=' ' && data[i]!='\t' && data[i]!='\n' && data[i]!='\r' ){ i += 1; } /* TODO: maybe require both data[i-1]=='>' && data[link_offset-1]=='<' ? */ if( data[i-1]=='>' ) link_end = i-1; else link_end = i; /* optional spacer: (space | tab)* (newline | '\'' | '"' | '(' ) */ while( i<end && (data[i]==' ' || data[i]=='\t') ){ i++; } if( i<end && data[i]!='\n' && data[i]!='\r' |
︙ | ︙ | |||
2404 2405 2406 2407 2408 2409 2410 | id_end = i++; /* spacer: colon (space | tab)* */ if( i>=end || data[i]!=':' ) return 0; i++; while( i<end && (data[i]==' ' || data[i]=='\t') ){ i++; } | | < | 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 | id_end = i++; /* spacer: colon (space | tab)* */ if( i>=end || data[i]!=':' ) return 0; i++; while( i<end && (data[i]==' ' || data[i]=='\t') ){ i++; } /* passthrough truncated footnote definition */ if( i>=end ) return 0; if( build_ref_id(&fn.id, data+id_offset, id_end-id_offset)<0 ) return 0; /* footnote's text may start on the same line */ if( data[i]!='\n' && data[i]!='\r' ){ const size_t j = i; |
︙ | ︙ | |||
2524 2525 2526 2527 2528 2529 2530 | * copying everything else into "text" */ beg = 0; for(const size_t size = blob_size(ib); beg<size ;){ const char* const data = blob_buffer(ib); if( is_ref(data, beg, size, &end, &rndr.refs) ){ beg = end; }else if(is_footnote(data, beg, size, &end, &rndr.notes.all)){ | < | 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 | * copying everything else into "text" */ beg = 0; for(const size_t size = blob_size(ib); beg<size ;){ const char* const data = blob_buffer(ib); if( is_ref(data, beg, size, &end, &rndr.refs) ){ beg = end; }else if(is_footnote(data, beg, size, &end, &rndr.notes.all)){ beg = end; }else{ /* skipping to the next line */ end = beg; while( end<size && data[end]!='\n' && data[end]!='\r' ){ end += 1; } /* adding the line body if present */ |
︙ | ︙ |