Fossil SCM
Merge the Markdown label enhancement from trunk.
Commit
ef15cfce3084a388c61a7696b7cbda01bba7c0e498a0d638a3497a1638015e31
Parent
f312c1829218739…
2 files changed
+42
-1
+2
+42
-1
| --- src/markdown_html.c | ||
| +++ src/markdown_html.c | ||
| @@ -216,20 +216,61 @@ | ||
| 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 | + /* | |
| 235 | + ** The GitHub "slugify" algorithm converts the text of a markdown header | |
| 236 | + ** into a ID for that header. The algorithm is: | |
| 237 | + ** | |
| 238 | + ** 1. ASCII alphanumerics -> convert to lower case | |
| 239 | + ** 2. Spaces, hyphens, underscores -> convert to '-' | |
| 240 | + ** 3. Non-ASCII -> preserve as-is | |
| 241 | + ** 4. Other punctuation -> remove | |
| 242 | + ** 5. Multiple consecutive dashes -> collapse to one | |
| 243 | + ** 6. Leading and trailing dashes -> remove | |
| 244 | + ** 7. Markup <...> and &...; -> remove | |
| 245 | + ** | |
| 246 | + ** This implementation does the conversion in-place. | |
| 247 | + */ | |
| 248 | + for(i=j=0; z[i]; i++){ | |
| 249 | + if( fossil_isalnum(z[i]) ){ | |
| 250 | + z[j++] = fossil_tolower(z[i]); | |
| 251 | + }else if( fossil_isspace(z[i]) || z[i]=='-' || z[i]=='_' ){ | |
| 252 | + if( j>0 && z[j-1]!='-' ) z[j++] = '-'; | |
| 253 | + }else if( z[i]=='<' ){ | |
| 254 | + do{ i++; }while( z[i]!=0 && z[i]!='>' ); | |
| 255 | + }else if( z[i]=='&' ){ | |
| 256 | + do{ i++; }while( z[i]!=0 && z[i]!=';' ); | |
| 257 | + }else if( (z[i]&0x80)!=0 ){ | |
| 258 | + z[j++] = z[i]; | |
| 259 | + } | |
| 260 | + } | |
| 261 | + if( j>0 && z[j-1]=='-' ) j--; | |
| 262 | + z[j] = 0; | |
| 263 | + } | |
| 264 | + if( j>0 ){ | |
| 265 | + blob_appendf(ob, "<h%d id=\"%s\">", level, z); | |
| 266 | + }else{ | |
| 267 | + blob_appendf(ob, "<h%d>", level); | |
| 268 | + } | |
| 229 | 269 | blob_appendb(ob, text); |
| 230 | 270 | blob_appendf(ob, "</h%d>", level); |
| 271 | + fossil_free(z); | |
| 231 | 272 | } |
| 232 | 273 | |
| 233 | 274 | static void html_hrule(struct Blob *ob, void *opaque){ |
| 234 | 275 | INTER_BLOCK(ob); |
| 235 | 276 | blob_append_literal(ob, "<hr>\n"); |
| 236 | 277 |
| --- src/markdown_html.c | |
| +++ src/markdown_html.c | |
| @@ -216,20 +216,61 @@ | |
| 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,61 @@ | |
| 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 | /* |
| 235 | ** The GitHub "slugify" algorithm converts the text of a markdown header |
| 236 | ** into a ID for that header. The algorithm is: |
| 237 | ** |
| 238 | ** 1. ASCII alphanumerics -> convert to lower case |
| 239 | ** 2. Spaces, hyphens, underscores -> convert to '-' |
| 240 | ** 3. Non-ASCII -> preserve as-is |
| 241 | ** 4. Other punctuation -> remove |
| 242 | ** 5. Multiple consecutive dashes -> collapse to one |
| 243 | ** 6. Leading and trailing dashes -> remove |
| 244 | ** 7. Markup <...> and &...; -> remove |
| 245 | ** |
| 246 | ** This implementation does the conversion in-place. |
| 247 | */ |
| 248 | for(i=j=0; z[i]; i++){ |
| 249 | if( fossil_isalnum(z[i]) ){ |
| 250 | z[j++] = fossil_tolower(z[i]); |
| 251 | }else if( fossil_isspace(z[i]) || z[i]=='-' || z[i]=='_' ){ |
| 252 | if( j>0 && z[j-1]!='-' ) z[j++] = '-'; |
| 253 | }else if( z[i]=='<' ){ |
| 254 | do{ i++; }while( z[i]!=0 && z[i]!='>' ); |
| 255 | }else if( z[i]=='&' ){ |
| 256 | do{ i++; }while( z[i]!=0 && z[i]!=';' ); |
| 257 | }else if( (z[i]&0x80)!=0 ){ |
| 258 | z[j++] = z[i]; |
| 259 | } |
| 260 | } |
| 261 | if( j>0 && z[j-1]=='-' ) j--; |
| 262 | z[j] = 0; |
| 263 | } |
| 264 | if( j>0 ){ |
| 265 | blob_appendf(ob, "<h%d id=\"%s\">", level, z); |
| 266 | }else{ |
| 267 | blob_appendf(ob, "<h%d>", level); |
| 268 | } |
| 269 | blob_appendb(ob, text); |
| 270 | blob_appendf(ob, "</h%d>", level); |
| 271 | fossil_free(z); |
| 272 | } |
| 273 | |
| 274 | static void html_hrule(struct Blob *ob, void *opaque){ |
| 275 | INTER_BLOCK(ob); |
| 276 | blob_append_literal(ob, "<hr>\n"); |
| 277 |
+2
| --- www/changes.wiki | ||
| +++ www/changes.wiki | ||
| @@ -44,10 +44,12 @@ | ||
| 44 | 44 | <li> "No-graph" timelines (using the "ng" query parameter) now show |
| 45 | 45 | branch colors and bare check-in circles on the left. The check-in |
| 46 | 46 | circles appear, but no lines connecting them. |
| 47 | 47 | ([/timeline?ng|example]). |
| 48 | 48 | </ol> |
| 49 | + <li> Labels in Markdown now have IDs generated using the GitHub "slugify" | |
| 50 | + algorithm. | |
| 49 | 51 | <li> The [/help/timeline|timeline command] is enhanced with the new options |
| 50 | 52 | "<tt>-u|--for-user</tt>" to filter by user, and "<tt>-r</tt>" to display |
| 51 | 53 | entries in chronological order. |
| 52 | 54 | <li> The [/help/open|open command]'s new "<tt>--reopen REPOFILE</tt>" flag |
| 53 | 55 | can be used to fix a checkout after moving its repository file. |
| 54 | 56 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -44,10 +44,12 @@ | |
| 44 | <li> "No-graph" timelines (using the "ng" query parameter) now show |
| 45 | branch colors and bare check-in circles on the left. The check-in |
| 46 | circles appear, but no lines connecting them. |
| 47 | ([/timeline?ng|example]). |
| 48 | </ol> |
| 49 | <li> The [/help/timeline|timeline command] is enhanced with the new options |
| 50 | "<tt>-u|--for-user</tt>" to filter by user, and "<tt>-r</tt>" to display |
| 51 | entries in chronological order. |
| 52 | <li> The [/help/open|open command]'s new "<tt>--reopen REPOFILE</tt>" flag |
| 53 | can be used to fix a checkout after moving its repository file. |
| 54 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -44,10 +44,12 @@ | |
| 44 | <li> "No-graph" timelines (using the "ng" query parameter) now show |
| 45 | branch colors and bare check-in circles on the left. The check-in |
| 46 | circles appear, but no lines connecting them. |
| 47 | ([/timeline?ng|example]). |
| 48 | </ol> |
| 49 | <li> Labels in Markdown now have IDs generated using the GitHub "slugify" |
| 50 | algorithm. |
| 51 | <li> The [/help/timeline|timeline command] is enhanced with the new options |
| 52 | "<tt>-u|--for-user</tt>" to filter by user, and "<tt>-r</tt>" to display |
| 53 | entries in chronological order. |
| 54 | <li> The [/help/open|open command]'s new "<tt>--reopen REPOFILE</tt>" flag |
| 55 | can be used to fix a checkout after moving its repository file. |
| 56 |