Fossil SCM
When markdown begins with a <h1> HTML element, consider the content of that element to be the title of the document.
Commit
cc7f4df41743ffc010e82931069358301eaa7c75
Parent
a3691d767964e76…
2 files changed
+15
-4
+3
-3
+15
-4
| --- src/markdown_html.c | ||
| +++ src/markdown_html.c | ||
| @@ -99,15 +99,25 @@ | ||
| 99 | 99 | BLOB_APPEND_LITERAL(ob, "</div>\n"); |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | 102 | static void html_raw_block(struct Blob *ob, struct Blob *text, void *opaque){ |
| 103 | 103 | char *data = blob_buffer(text); |
| 104 | - size_t first = 0, size = blob_size(text); | |
| 104 | + size_t size = blob_size(text); | |
| 105 | + while( size>0 && fossil_isspace(data[0]) ){ data++; size--; } | |
| 106 | + while( size>0 && fossil_isspace(data[size-1]) ){ size--; } | |
| 107 | + /* If the first raw block is an <h1> element, then use it as the title. */ | |
| 108 | + if( blob_size(ob)<=PROLOG_SIZE | |
| 109 | + && size>9 | |
| 110 | + && sqlite3_strnicmp("<h1",data,3)==0 | |
| 111 | + && sqlite3_strnicmp("</h1>", &data[size-5],5)==0 | |
| 112 | + ){ | |
| 113 | + Blob *title = (Blob*)opaque; | |
| 114 | + int nTag = htmlTagLength(data); | |
| 115 | + blob_append(title, data+nTag, size - nTag - 5); | |
| 116 | + } | |
| 105 | 117 | INTER_BLOCK(ob); |
| 106 | - while( first<size && data[first]=='\n' ) first++; | |
| 107 | - while( size>first && data[size-1]=='\n' ) size--; | |
| 108 | - blob_append(ob, data+first, size-first); | |
| 118 | + blob_append(ob, data, size); | |
| 109 | 119 | BLOB_APPEND_LITERAL(ob, "\n"); |
| 110 | 120 | } |
| 111 | 121 | |
| 112 | 122 | static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){ |
| 113 | 123 | INTER_BLOCK(ob); |
| @@ -254,10 +264,11 @@ | ||
| 254 | 264 | |
| 255 | 265 | |
| 256 | 266 | /* HTML span tags */ |
| 257 | 267 | |
| 258 | 268 | static int html_raw_span(struct Blob *ob, struct Blob *text, void *opaque){ |
| 269 | + /* If the document begins with a <h1> markup, take that as the header. */ | |
| 259 | 270 | BLOB_APPEND_BLOB(ob, text); |
| 260 | 271 | return 1; |
| 261 | 272 | } |
| 262 | 273 | |
| 263 | 274 | static int html_autolink( |
| 264 | 275 |
| --- src/markdown_html.c | |
| +++ src/markdown_html.c | |
| @@ -99,15 +99,25 @@ | |
| 99 | BLOB_APPEND_LITERAL(ob, "</div>\n"); |
| 100 | } |
| 101 | |
| 102 | static void html_raw_block(struct Blob *ob, struct Blob *text, void *opaque){ |
| 103 | char *data = blob_buffer(text); |
| 104 | size_t first = 0, size = blob_size(text); |
| 105 | INTER_BLOCK(ob); |
| 106 | while( first<size && data[first]=='\n' ) first++; |
| 107 | while( size>first && data[size-1]=='\n' ) size--; |
| 108 | blob_append(ob, data+first, size-first); |
| 109 | BLOB_APPEND_LITERAL(ob, "\n"); |
| 110 | } |
| 111 | |
| 112 | static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){ |
| 113 | INTER_BLOCK(ob); |
| @@ -254,10 +264,11 @@ | |
| 254 | |
| 255 | |
| 256 | /* HTML span tags */ |
| 257 | |
| 258 | static int html_raw_span(struct Blob *ob, struct Blob *text, void *opaque){ |
| 259 | BLOB_APPEND_BLOB(ob, text); |
| 260 | return 1; |
| 261 | } |
| 262 | |
| 263 | static int html_autolink( |
| 264 |
| --- src/markdown_html.c | |
| +++ src/markdown_html.c | |
| @@ -99,15 +99,25 @@ | |
| 99 | BLOB_APPEND_LITERAL(ob, "</div>\n"); |
| 100 | } |
| 101 | |
| 102 | static void html_raw_block(struct Blob *ob, struct Blob *text, void *opaque){ |
| 103 | char *data = blob_buffer(text); |
| 104 | size_t size = blob_size(text); |
| 105 | while( size>0 && fossil_isspace(data[0]) ){ data++; size--; } |
| 106 | while( size>0 && fossil_isspace(data[size-1]) ){ size--; } |
| 107 | /* If the first raw block is an <h1> element, then use it as the title. */ |
| 108 | if( blob_size(ob)<=PROLOG_SIZE |
| 109 | && size>9 |
| 110 | && sqlite3_strnicmp("<h1",data,3)==0 |
| 111 | && sqlite3_strnicmp("</h1>", &data[size-5],5)==0 |
| 112 | ){ |
| 113 | Blob *title = (Blob*)opaque; |
| 114 | int nTag = htmlTagLength(data); |
| 115 | blob_append(title, data+nTag, size - nTag - 5); |
| 116 | } |
| 117 | INTER_BLOCK(ob); |
| 118 | blob_append(ob, data, size); |
| 119 | BLOB_APPEND_LITERAL(ob, "\n"); |
| 120 | } |
| 121 | |
| 122 | static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){ |
| 123 | INTER_BLOCK(ob); |
| @@ -254,10 +264,11 @@ | |
| 264 | |
| 265 | |
| 266 | /* HTML span tags */ |
| 267 | |
| 268 | static int html_raw_span(struct Blob *ob, struct Blob *text, void *opaque){ |
| 269 | /* If the document begins with a <h1> markup, take that as the header. */ |
| 270 | BLOB_APPEND_BLOB(ob, text); |
| 271 | return 1; |
| 272 | } |
| 273 | |
| 274 | static int html_autolink( |
| 275 |
+3
-3
| --- src/wikiformat.c | ||
| +++ src/wikiformat.c | ||
| @@ -467,11 +467,11 @@ | ||
| 467 | 467 | ** z points to a "<" character. Check to see if this is the start of |
| 468 | 468 | ** a valid markup. If it is, return the total number of characters in |
| 469 | 469 | ** the markup including the initial "<" and the terminating ">". If |
| 470 | 470 | ** it is not well-formed markup, return 0. |
| 471 | 471 | */ |
| 472 | -static int markupLength(const char *z){ | |
| 472 | +int htmlTagLength(const char *z){ | |
| 473 | 473 | int n = 1; |
| 474 | 474 | int inparen = 0; |
| 475 | 475 | int c; |
| 476 | 476 | if( z[n]=='/' ){ n++; } |
| 477 | 477 | if( !fossil_isalpha(z[n]) ) return 0; |
| @@ -662,11 +662,11 @@ | ||
| 662 | 662 | ** characters in that token. Write the token type into *pTokenType. |
| 663 | 663 | */ |
| 664 | 664 | static int nextWikiToken(const char *z, Renderer *p, int *pTokenType){ |
| 665 | 665 | int n; |
| 666 | 666 | if( z[0]=='<' ){ |
| 667 | - n = markupLength(z); | |
| 667 | + n = htmlTagLength(z); | |
| 668 | 668 | if( n>0 ){ |
| 669 | 669 | *pTokenType = TOKEN_MARKUP; |
| 670 | 670 | return n; |
| 671 | 671 | }else{ |
| 672 | 672 | *pTokenType = TOKEN_CHARACTER; |
| @@ -1972,11 +1972,11 @@ | ||
| 1972 | 1972 | */ |
| 1973 | 1973 | static int nextHtmlToken(const char *z){ |
| 1974 | 1974 | int n; |
| 1975 | 1975 | char c; |
| 1976 | 1976 | if( (c=z[0])=='<' ){ |
| 1977 | - n = markupLength(z); | |
| 1977 | + n = htmlTagLength(z); | |
| 1978 | 1978 | if( n<=0 ) n = 1; |
| 1979 | 1979 | }else if( fossil_isspace(c) ){ |
| 1980 | 1980 | for(n=1; z[n] && fossil_isspace(z[n]); n++){} |
| 1981 | 1981 | }else if( c=='&' ){ |
| 1982 | 1982 | n = z[1]=='#' ? 2 : 1; |
| 1983 | 1983 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -467,11 +467,11 @@ | |
| 467 | ** z points to a "<" character. Check to see if this is the start of |
| 468 | ** a valid markup. If it is, return the total number of characters in |
| 469 | ** the markup including the initial "<" and the terminating ">". If |
| 470 | ** it is not well-formed markup, return 0. |
| 471 | */ |
| 472 | static int markupLength(const char *z){ |
| 473 | int n = 1; |
| 474 | int inparen = 0; |
| 475 | int c; |
| 476 | if( z[n]=='/' ){ n++; } |
| 477 | if( !fossil_isalpha(z[n]) ) return 0; |
| @@ -662,11 +662,11 @@ | |
| 662 | ** characters in that token. Write the token type into *pTokenType. |
| 663 | */ |
| 664 | static int nextWikiToken(const char *z, Renderer *p, int *pTokenType){ |
| 665 | int n; |
| 666 | if( z[0]=='<' ){ |
| 667 | n = markupLength(z); |
| 668 | if( n>0 ){ |
| 669 | *pTokenType = TOKEN_MARKUP; |
| 670 | return n; |
| 671 | }else{ |
| 672 | *pTokenType = TOKEN_CHARACTER; |
| @@ -1972,11 +1972,11 @@ | |
| 1972 | */ |
| 1973 | static int nextHtmlToken(const char *z){ |
| 1974 | int n; |
| 1975 | char c; |
| 1976 | if( (c=z[0])=='<' ){ |
| 1977 | n = markupLength(z); |
| 1978 | if( n<=0 ) n = 1; |
| 1979 | }else if( fossil_isspace(c) ){ |
| 1980 | for(n=1; z[n] && fossil_isspace(z[n]); n++){} |
| 1981 | }else if( c=='&' ){ |
| 1982 | n = z[1]=='#' ? 2 : 1; |
| 1983 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -467,11 +467,11 @@ | |
| 467 | ** z points to a "<" character. Check to see if this is the start of |
| 468 | ** a valid markup. If it is, return the total number of characters in |
| 469 | ** the markup including the initial "<" and the terminating ">". If |
| 470 | ** it is not well-formed markup, return 0. |
| 471 | */ |
| 472 | int htmlTagLength(const char *z){ |
| 473 | int n = 1; |
| 474 | int inparen = 0; |
| 475 | int c; |
| 476 | if( z[n]=='/' ){ n++; } |
| 477 | if( !fossil_isalpha(z[n]) ) return 0; |
| @@ -662,11 +662,11 @@ | |
| 662 | ** characters in that token. Write the token type into *pTokenType. |
| 663 | */ |
| 664 | static int nextWikiToken(const char *z, Renderer *p, int *pTokenType){ |
| 665 | int n; |
| 666 | if( z[0]=='<' ){ |
| 667 | n = htmlTagLength(z); |
| 668 | if( n>0 ){ |
| 669 | *pTokenType = TOKEN_MARKUP; |
| 670 | return n; |
| 671 | }else{ |
| 672 | *pTokenType = TOKEN_CHARACTER; |
| @@ -1972,11 +1972,11 @@ | |
| 1972 | */ |
| 1973 | static int nextHtmlToken(const char *z){ |
| 1974 | int n; |
| 1975 | char c; |
| 1976 | if( (c=z[0])=='<' ){ |
| 1977 | n = htmlTagLength(z); |
| 1978 | if( n<=0 ) n = 1; |
| 1979 | }else if( fossil_isspace(c) ){ |
| 1980 | for(n=1; z[n] && fossil_isspace(z[n]); n++){} |
| 1981 | }else if( c=='&' ){ |
| 1982 | n = z[1]=='#' ? 2 : 1; |
| 1983 |