Fossil SCM
Attempt to add IDs to headers in markdown, the same way that GitHub does. Needs additional testing to confirm that unusual characters in headers are handled reasonably.
Commit
21cbb8c467a1a360490e69292b135e02123cd171183c78bd7fdae58aadf87cae
Parent
b0188ce122c43b4…
1 file changed
+24
-1
+24
-1
| --- src/markdown_html.c | ||
| +++ src/markdown_html.c | ||
| @@ -216,20 +216,43 @@ | ||
| 216 | 216 | struct Blob *text, |
| 217 | 217 | int level, |
| 218 | 218 | void *opaque |
| 219 | 219 | ){ |
| 220 | 220 | struct Blob *title = ((MarkdownToHtml*)opaque)->output_title; |
| 221 | + char *z = 0; | |
| 222 | + int i,j; | |
| 221 | 223 | /* The first header at the beginning of a text is considered as |
| 222 | 224 | * a title and not output. */ |
| 223 | 225 | if( blob_size(ob)<=PROLOG_SIZE && title!=0 && blob_size(title)==0 ){ |
| 224 | 226 | blob_appendb(title, text); |
| 225 | 227 | return; |
| 226 | 228 | } |
| 227 | 229 | INTER_BLOCK(ob); |
| 228 | - blob_appendf(ob, "<h%d>", level); | |
| 230 | + z = fossil_strdup(blob_buffer(text)); | |
| 231 | + if( z==0 ){ | |
| 232 | + j = 0; | |
| 233 | + }else{ | |
| 234 | + for(i=j=0; z[i]; i++){ | |
| 235 | + if( fossil_isalnum(z[i]) ){ | |
| 236 | + z[j++] = fossil_tolower(z[i]); | |
| 237 | + }else if( fossil_isspace(z[i]) && j>0 && fossil_isalnum(z[j-1]) ){ | |
| 238 | + z[j++] = '-'; | |
| 239 | + }else if( z[i]=='<' ){ | |
| 240 | + do{ i++; }while( z[i]!=0 && z[i]!='>' ); | |
| 241 | + } | |
| 242 | + } | |
| 243 | + if( j>0 && z[j-1]=='-' ) j--; | |
| 244 | + z[j] = 0; | |
| 245 | + } | |
| 246 | + if( j>0 ){ | |
| 247 | + blob_appendf(ob, "<h%d id=\"%s\">", level, z); | |
| 248 | + }else{ | |
| 249 | + blob_appendf(ob, "<h%d>", level); | |
| 250 | + } | |
| 229 | 251 | blob_appendb(ob, text); |
| 230 | 252 | blob_appendf(ob, "</h%d>", level); |
| 253 | + fossil_free(z); | |
| 231 | 254 | } |
| 232 | 255 | |
| 233 | 256 | static void html_hrule(struct Blob *ob, void *opaque){ |
| 234 | 257 | INTER_BLOCK(ob); |
| 235 | 258 | blob_append_literal(ob, "<hr>\n"); |
| 236 | 259 |
| --- src/markdown_html.c | |
| +++ src/markdown_html.c | |
| @@ -216,20 +216,43 @@ | |
| 216 | struct Blob *text, |
| 217 | int level, |
| 218 | void *opaque |
| 219 | ){ |
| 220 | struct Blob *title = ((MarkdownToHtml*)opaque)->output_title; |
| 221 | /* The first header at the beginning of a text is considered as |
| 222 | * a title and not output. */ |
| 223 | if( blob_size(ob)<=PROLOG_SIZE && title!=0 && blob_size(title)==0 ){ |
| 224 | blob_appendb(title, text); |
| 225 | return; |
| 226 | } |
| 227 | INTER_BLOCK(ob); |
| 228 | blob_appendf(ob, "<h%d>", level); |
| 229 | blob_appendb(ob, text); |
| 230 | blob_appendf(ob, "</h%d>", level); |
| 231 | } |
| 232 | |
| 233 | static void html_hrule(struct Blob *ob, void *opaque){ |
| 234 | INTER_BLOCK(ob); |
| 235 | blob_append_literal(ob, "<hr>\n"); |
| 236 |
| --- src/markdown_html.c | |
| +++ src/markdown_html.c | |
| @@ -216,20 +216,43 @@ | |
| 216 | struct Blob *text, |
| 217 | int level, |
| 218 | void *opaque |
| 219 | ){ |
| 220 | struct Blob *title = ((MarkdownToHtml*)opaque)->output_title; |
| 221 | char *z = 0; |
| 222 | int i,j; |
| 223 | /* The first header at the beginning of a text is considered as |
| 224 | * a title and not output. */ |
| 225 | if( blob_size(ob)<=PROLOG_SIZE && title!=0 && blob_size(title)==0 ){ |
| 226 | blob_appendb(title, text); |
| 227 | return; |
| 228 | } |
| 229 | INTER_BLOCK(ob); |
| 230 | z = fossil_strdup(blob_buffer(text)); |
| 231 | if( z==0 ){ |
| 232 | j = 0; |
| 233 | }else{ |
| 234 | for(i=j=0; z[i]; i++){ |
| 235 | if( fossil_isalnum(z[i]) ){ |
| 236 | z[j++] = fossil_tolower(z[i]); |
| 237 | }else if( fossil_isspace(z[i]) && j>0 && fossil_isalnum(z[j-1]) ){ |
| 238 | z[j++] = '-'; |
| 239 | }else if( z[i]=='<' ){ |
| 240 | do{ i++; }while( z[i]!=0 && z[i]!='>' ); |
| 241 | } |
| 242 | } |
| 243 | if( j>0 && z[j-1]=='-' ) j--; |
| 244 | z[j] = 0; |
| 245 | } |
| 246 | if( j>0 ){ |
| 247 | blob_appendf(ob, "<h%d id=\"%s\">", level, z); |
| 248 | }else{ |
| 249 | blob_appendf(ob, "<h%d>", level); |
| 250 | } |
| 251 | blob_appendb(ob, text); |
| 252 | blob_appendf(ob, "</h%d>", level); |
| 253 | fossil_free(z); |
| 254 | } |
| 255 | |
| 256 | static void html_hrule(struct Blob *ob, void *opaque){ |
| 257 | INTER_BLOCK(ob); |
| 258 | blob_append_literal(ob, "<hr>\n"); |
| 259 |