Fossil SCM
Provide a custom structure to the "opaque" pointer of the generic Markdown translator for use when translating Markdown into HTML.
Commit
b61dcef9e83750974a2771a1b572c99b74c65d98e28c30db2dbe37cc2d6213ed
Parent
4e757d8c4872802…
1 file changed
+15
-3
+15
-3
| --- src/markdown_html.c | ||
| +++ src/markdown_html.c | ||
| @@ -29,10 +29,19 @@ | ||
| 29 | 29 | struct Blob *output_title, |
| 30 | 30 | struct Blob *output_body); |
| 31 | 31 | |
| 32 | 32 | #endif /* INTERFACE */ |
| 33 | 33 | |
| 34 | +/* | |
| 35 | +** An instance of the following structure is passed through the | |
| 36 | +** "opaque" pointer. | |
| 37 | +*/ | |
| 38 | +typedef struct MarkdownToHtml MarkdownToHtml; | |
| 39 | +struct MarkdownToHtml { | |
| 40 | + Blob *output_title; /* Store the title here */ | |
| 41 | +}; | |
| 42 | + | |
| 34 | 43 | |
| 35 | 44 | /* INTER_BLOCK -- skip a line between block level elements */ |
| 36 | 45 | #define INTER_BLOCK(ob) \ |
| 37 | 46 | do { if( blob_size(ob)>0 ) blob_append_char(ob, '\n'); } while (0) |
| 38 | 47 | |
| @@ -132,11 +141,11 @@ | ||
| 132 | 141 | } |
| 133 | 142 | |
| 134 | 143 | static void html_blockhtml(struct Blob *ob, struct Blob *text, void *opaque){ |
| 135 | 144 | char *data = blob_buffer(text); |
| 136 | 145 | size_t size = blob_size(text); |
| 137 | - Blob *title = (Blob*)opaque; | |
| 146 | + Blob *title = ((MarkdownToHtml*)opaque)->output_title; | |
| 138 | 147 | while( size>0 && fossil_isspace(data[0]) ){ data++; size--; } |
| 139 | 148 | while( size>0 && fossil_isspace(data[size-1]) ){ size--; } |
| 140 | 149 | /* If the first raw block is an <h1> element, then use it as the title. */ |
| 141 | 150 | if( blob_size(ob)<=PROLOG_SIZE |
| 142 | 151 | && size>9 |
| @@ -171,11 +180,11 @@ | ||
| 171 | 180 | struct Blob *ob, |
| 172 | 181 | struct Blob *text, |
| 173 | 182 | int level, |
| 174 | 183 | void *opaque |
| 175 | 184 | ){ |
| 176 | - struct Blob *title = opaque; | |
| 185 | + struct Blob *title = ((MarkdownToHtml*)opaque)->output_title; | |
| 177 | 186 | /* The first header at the beginning of a text is considered as |
| 178 | 187 | * a title and not output. */ |
| 179 | 188 | if( blob_size(ob)<=PROLOG_SIZE && title!=0 && blob_size(title)==0 ){ |
| 180 | 189 | BLOB_APPEND_BLOB(title, text); |
| 181 | 190 | return; |
| @@ -569,10 +578,13 @@ | ||
| 569 | 578 | |
| 570 | 579 | /* misc. parameters */ |
| 571 | 580 | "*_", /* emph_chars */ |
| 572 | 581 | 0 /* opaque */ |
| 573 | 582 | }; |
| 574 | - html_renderer.opaque = output_title; | |
| 583 | + MarkdownToHtml context; | |
| 584 | + memset(&context, 0, sizeof(context)); | |
| 585 | + context.output_title = output_title; | |
| 586 | + html_renderer.opaque = &context; | |
| 575 | 587 | if( output_title ) blob_reset(output_title); |
| 576 | 588 | blob_reset(output_body); |
| 577 | 589 | markdown(output_body, input_markdown, &html_renderer); |
| 578 | 590 | } |
| 579 | 591 |
| --- src/markdown_html.c | |
| +++ src/markdown_html.c | |
| @@ -29,10 +29,19 @@ | |
| 29 | struct Blob *output_title, |
| 30 | struct Blob *output_body); |
| 31 | |
| 32 | #endif /* INTERFACE */ |
| 33 | |
| 34 | |
| 35 | /* INTER_BLOCK -- skip a line between block level elements */ |
| 36 | #define INTER_BLOCK(ob) \ |
| 37 | do { if( blob_size(ob)>0 ) blob_append_char(ob, '\n'); } while (0) |
| 38 | |
| @@ -132,11 +141,11 @@ | |
| 132 | } |
| 133 | |
| 134 | static void html_blockhtml(struct Blob *ob, struct Blob *text, void *opaque){ |
| 135 | char *data = blob_buffer(text); |
| 136 | size_t size = blob_size(text); |
| 137 | Blob *title = (Blob*)opaque; |
| 138 | while( size>0 && fossil_isspace(data[0]) ){ data++; size--; } |
| 139 | while( size>0 && fossil_isspace(data[size-1]) ){ size--; } |
| 140 | /* If the first raw block is an <h1> element, then use it as the title. */ |
| 141 | if( blob_size(ob)<=PROLOG_SIZE |
| 142 | && size>9 |
| @@ -171,11 +180,11 @@ | |
| 171 | struct Blob *ob, |
| 172 | struct Blob *text, |
| 173 | int level, |
| 174 | void *opaque |
| 175 | ){ |
| 176 | struct Blob *title = opaque; |
| 177 | /* The first header at the beginning of a text is considered as |
| 178 | * a title and not output. */ |
| 179 | if( blob_size(ob)<=PROLOG_SIZE && title!=0 && blob_size(title)==0 ){ |
| 180 | BLOB_APPEND_BLOB(title, text); |
| 181 | return; |
| @@ -569,10 +578,13 @@ | |
| 569 | |
| 570 | /* misc. parameters */ |
| 571 | "*_", /* emph_chars */ |
| 572 | 0 /* opaque */ |
| 573 | }; |
| 574 | html_renderer.opaque = output_title; |
| 575 | if( output_title ) blob_reset(output_title); |
| 576 | blob_reset(output_body); |
| 577 | markdown(output_body, input_markdown, &html_renderer); |
| 578 | } |
| 579 |
| --- src/markdown_html.c | |
| +++ src/markdown_html.c | |
| @@ -29,10 +29,19 @@ | |
| 29 | struct Blob *output_title, |
| 30 | struct Blob *output_body); |
| 31 | |
| 32 | #endif /* INTERFACE */ |
| 33 | |
| 34 | /* |
| 35 | ** An instance of the following structure is passed through the |
| 36 | ** "opaque" pointer. |
| 37 | */ |
| 38 | typedef struct MarkdownToHtml MarkdownToHtml; |
| 39 | struct MarkdownToHtml { |
| 40 | Blob *output_title; /* Store the title here */ |
| 41 | }; |
| 42 | |
| 43 | |
| 44 | /* INTER_BLOCK -- skip a line between block level elements */ |
| 45 | #define INTER_BLOCK(ob) \ |
| 46 | do { if( blob_size(ob)>0 ) blob_append_char(ob, '\n'); } while (0) |
| 47 | |
| @@ -132,11 +141,11 @@ | |
| 141 | } |
| 142 | |
| 143 | static void html_blockhtml(struct Blob *ob, struct Blob *text, void *opaque){ |
| 144 | char *data = blob_buffer(text); |
| 145 | size_t size = blob_size(text); |
| 146 | Blob *title = ((MarkdownToHtml*)opaque)->output_title; |
| 147 | while( size>0 && fossil_isspace(data[0]) ){ data++; size--; } |
| 148 | while( size>0 && fossil_isspace(data[size-1]) ){ size--; } |
| 149 | /* If the first raw block is an <h1> element, then use it as the title. */ |
| 150 | if( blob_size(ob)<=PROLOG_SIZE |
| 151 | && size>9 |
| @@ -171,11 +180,11 @@ | |
| 180 | struct Blob *ob, |
| 181 | struct Blob *text, |
| 182 | int level, |
| 183 | void *opaque |
| 184 | ){ |
| 185 | struct Blob *title = ((MarkdownToHtml*)opaque)->output_title; |
| 186 | /* The first header at the beginning of a text is considered as |
| 187 | * a title and not output. */ |
| 188 | if( blob_size(ob)<=PROLOG_SIZE && title!=0 && blob_size(title)==0 ){ |
| 189 | BLOB_APPEND_BLOB(title, text); |
| 190 | return; |
| @@ -569,10 +578,13 @@ | |
| 578 | |
| 579 | /* misc. parameters */ |
| 580 | "*_", /* emph_chars */ |
| 581 | 0 /* opaque */ |
| 582 | }; |
| 583 | MarkdownToHtml context; |
| 584 | memset(&context, 0, sizeof(context)); |
| 585 | context.output_title = output_title; |
| 586 | html_renderer.opaque = &context; |
| 587 | if( output_title ) blob_reset(output_title); |
| 588 | blob_reset(output_body); |
| 589 | markdown(output_body, input_markdown, &html_renderer); |
| 590 | } |
| 591 |