| 1 | # |
| 2 | # Patch managed by http://www.holgerschurig.de/patcher.html |
| 3 | # |
| 4 | # This patch is against htmldoc 1.8.24, and it hacks in support for |
| 5 | # correctly indenting the <div class=""> sections in the SWIG manual. |
| 6 | # This patch should only be used until the 1.9 branch of htmldoc |
| 7 | # stabalizes, since the 1.9 branch includes true CSS1 support. |
| 8 | # |
| 9 | # This patch only affects the PDF generation, an unpatched htmldoc |
| 10 | # creates the one-page html documentation just fine. |
| 11 | # |
| 12 | --- htmldoc-1.8.24/htmldoc/ps-pdf.cxx~margin-left |
| 13 | +++ htmldoc-1.8.24/htmldoc/ps-pdf.cxx |
| 14 | @@ -158,6 +158,7 @@ |
| 15 | # undef page_t |
| 16 | #endif // __hpux |
| 17 | |
| 18 | +extern int lookup_div_class(uchar *); |
| 19 | |
| 20 | /* |
| 21 | * Constants... |
| 22 | @@ -4188,9 +4189,24 @@ |
| 23 | para->child = para->last_child = NULL; |
| 24 | } |
| 25 | |
| 26 | - parse_doc(t->child, left, right, bottom, top, x, y, page, NULL, |
| 27 | + { |
| 28 | + int num_indent = 0; |
| 29 | + uchar *cname; |
| 30 | + |
| 31 | + if (cname = htmlGetVariable(t, (uchar *)"class")) { |
| 32 | + num_indent = lookup_div_class(cname); |
| 33 | + *left += 5.0f * num_indent; |
| 34 | + *x = *left; |
| 35 | + } |
| 36 | + |
| 37 | + parse_doc(t->child, left, right, bottom, top, x, y, page, NULL, |
| 38 | needspace); |
| 39 | |
| 40 | + if (num_indent > 0) { |
| 41 | + *left -= 5.0f * num_indent; |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | if (para->child != NULL) |
| 46 | { |
| 47 | parse_paragraph(para, *left, *right, *bottom, *top, x, y, page, *needspace); |
| 48 | --- htmldoc-1.8.24/htmldoc/htmldoc.cxx~margin-left |
| 49 | +++ htmldoc-1.8.24/htmldoc/htmldoc.cxx |
| 50 | @@ -62,6 +62,8 @@ |
| 51 | const char *__XOS2RedirRoot(const char *); |
| 52 | } |
| 53 | #endif |
| 54 | + |
| 55 | +extern void parse_style(char *); |
| 56 | |
| 57 | |
| 58 | /* |
| 59 | @@ -2140,6 +2142,10 @@ |
| 60 | } |
| 61 | else if (strcmp(temp, "--cookies") == 0) |
| 62 | file_cookies(temp2); |
| 63 | + else if (strcmp(temp, "--stylesheet") == 0) |
| 64 | + { |
| 65 | + parse_style(temp2); |
| 66 | + } |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | --- /dev/null |
| 71 | +++ htmldoc-1.8.24/htmldoc/style.cxx |
| 72 | @@ -0,0 +1,185 @@ |
| 73 | +/* Extreamly simple parsing routines for CSS style sheets. |
| 74 | + * We only parse div.class { } sections, and only look |
| 75 | + * for margin-left: <num>em; |
| 76 | + * |
| 77 | + * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu> |
| 78 | + * |
| 79 | + * Released under GNU GPL v2 or above. |
| 80 | + */ |
| 81 | + |
| 82 | +#include <stdio.h> |
| 83 | +#include <stdlib.h> |
| 84 | +#include <fcntl.h> |
| 85 | +#include <string.h> |
| 86 | +#include <ctype.h> |
| 87 | + |
| 88 | +#include "types.h" |
| 89 | + |
| 90 | +#define BUFF_SIZE 512 |
| 91 | + |
| 92 | +struct div_entry { |
| 93 | + uchar class_name[BUFF_SIZE]; |
| 94 | + int indent; |
| 95 | + struct div_entry *next; |
| 96 | +}; |
| 97 | + |
| 98 | +static struct div_entry *head = 0; |
| 99 | + |
| 100 | +/* These are the parsing states */ |
| 101 | +#define IGNORE_TILL_SEMI 0 |
| 102 | +#define IGNORE_TILL_CLOSE_BRACE 1 |
| 103 | +#define READING_DIV 2 |
| 104 | +#define READING_CLASS 3 |
| 105 | +#define READING_ATTRIBUTE 4 |
| 106 | +#define READING_NUM 5 |
| 107 | +#define CHECKING_ONLY_DIV 6 |
| 108 | + |
| 109 | +static int at_eof = 0; |
| 110 | + |
| 111 | +static int strucmp(uchar *a, uchar *b) { |
| 112 | + int i; |
| 113 | + for (i = 0; a[i] && b[i]; i++) { |
| 114 | + if (a[i] < b[i]) return -1; |
| 115 | + if (a[i] > b[i]) return 1; |
| 116 | + } |
| 117 | + /* This isn't right, but who cares...*/ |
| 118 | + if (a[i] || b[i]) return 1; |
| 119 | + return 0; |
| 120 | +} |
| 121 | + |
| 122 | +static int read_word(FILE *f, const char *word) { |
| 123 | + char c; |
| 124 | + for (int idx = 0; word[idx]; idx++) { |
| 125 | + c = getc(f); |
| 126 | + if (c == EOF) { |
| 127 | + at_eof = 1; |
| 128 | + return 0; |
| 129 | + } |
| 130 | + if (c != word[idx]) |
| 131 | + return 0; |
| 132 | + } |
| 133 | + return 1; |
| 134 | +} |
| 135 | + |
| 136 | +int lookup_div_class(uchar *name) { |
| 137 | + struct div_entry *node = head; |
| 138 | + |
| 139 | + while (node) { |
| 140 | + if (strucmp(node->class_name, name) == 0) |
| 141 | + return node->indent; |
| 142 | + node = node->next; |
| 143 | + } |
| 144 | + |
| 145 | + return 0; |
| 146 | +} |
| 147 | + |
| 148 | +void parse_style(char *fname) { |
| 149 | + FILE *f; |
| 150 | + char c; |
| 151 | + int state; |
| 152 | + struct div_entry *cur = 0; |
| 153 | + int class_idx = 0; |
| 154 | + char num[BUFF_SIZE]; |
| 155 | + int num_idx = 0; |
| 156 | + |
| 157 | + if (!fname) return; |
| 158 | + |
| 159 | + f = fopen(fname, "r"); |
| 160 | + if (!f) { |
| 161 | + fprintf(stderr, "Unable to parse style\n"); |
| 162 | + return; |
| 163 | + } |
| 164 | + |
| 165 | + state = READING_DIV; |
| 166 | + while (!at_eof && (c = getc(f)) != EOF) { |
| 167 | + switch (state) { |
| 168 | + |
| 169 | + case IGNORE_TILL_SEMI: |
| 170 | + if (c == ';') |
| 171 | + state = READING_ATTRIBUTE; |
| 172 | + break; |
| 173 | + |
| 174 | + case IGNORE_TILL_CLOSE_BRACE: |
| 175 | + if (c == '}') |
| 176 | + state = READING_DIV; |
| 177 | + break; |
| 178 | + |
| 179 | + case READING_DIV: |
| 180 | + if (c != ' ' && c != '\t' && c != '\n') { |
| 181 | + if (c == 'd' && read_word(f, "iv.")) { |
| 182 | + state = READING_CLASS; |
| 183 | + cur = (struct div_entry *) malloc(sizeof(struct div_entry)); |
| 184 | + memset(cur, 0, sizeof(struct div_entry)); |
| 185 | + class_idx = 0; |
| 186 | + } else |
| 187 | + state = IGNORE_TILL_CLOSE_BRACE; |
| 188 | + } |
| 189 | + break; |
| 190 | + |
| 191 | + case READING_CLASS: |
| 192 | + if (isalpha(c)) { |
| 193 | + if (class_idx >= BUFF_SIZE-1) { |
| 194 | + fprintf(stderr, "class size %s too long\n", cur->class_name); |
| 195 | + free(cur); |
| 196 | + state = IGNORE_TILL_CLOSE_BRACE; |
| 197 | + } else { |
| 198 | + cur->class_name[class_idx++] = c; |
| 199 | + } |
| 200 | + } else { |
| 201 | + if (c == '{') { |
| 202 | + cur->next = head; |
| 203 | + head = cur; |
| 204 | + state = READING_ATTRIBUTE; |
| 205 | + } else |
| 206 | + state = CHECKING_ONLY_DIV; |
| 207 | + } |
| 208 | + break; |
| 209 | + |
| 210 | + case READING_ATTRIBUTE: |
| 211 | + if (c != ' ' && c != '\t' && c != '\n') { |
| 212 | + if (c == '}') |
| 213 | + state = READING_DIV; |
| 214 | + else { |
| 215 | + if (c == 'm' && read_word(f, "argin-left:")) { |
| 216 | + num_idx = 0; |
| 217 | + memset(num, 0, sizeof(num)); |
| 218 | + state = READING_NUM; |
| 219 | + } else { |
| 220 | + state = IGNORE_TILL_SEMI; |
| 221 | + } |
| 222 | + } |
| 223 | + } |
| 224 | + break; |
| 225 | + |
| 226 | + case READING_NUM: |
| 227 | + if (isdigit(c)) { |
| 228 | + if (num_idx >= BUFF_SIZE - 1) { |
| 229 | + fprintf(stderr, "Number too long\n"); |
| 230 | + state = IGNORE_TILL_SEMI; |
| 231 | + } else { |
| 232 | + num[num_idx++] = c; |
| 233 | + } |
| 234 | + } else if (c != ' ' && c != '\t') { |
| 235 | + if (num_idx > 0 && c == 'e' && read_word(f, "m")) |
| 236 | + cur->indent = atoi(num); |
| 237 | + state = IGNORE_TILL_SEMI; |
| 238 | + } |
| 239 | + break; |
| 240 | + |
| 241 | + case CHECKING_ONLY_DIV: |
| 242 | + if (c != ' ' && c != '\t' && c != '\n') { |
| 243 | + if (c == '{') { |
| 244 | + cur->next = head; |
| 245 | + head = cur; |
| 246 | + state = READING_ATTRIBUTE; |
| 247 | + } else { |
| 248 | + free(cur); |
| 249 | + state = IGNORE_TILL_CLOSE_BRACE; |
| 250 | + } |
| 251 | + } |
| 252 | + break; |
| 253 | + } |
| 254 | + } |
| 255 | + |
| 256 | + fclose(f); |
| 257 | +} |
| 258 | --- htmldoc-1.8.24/htmldoc/Makefile~margin-left |
| 259 | +++ htmldoc-1.8.24/htmldoc/Makefile |
| 260 | @@ -35,7 +35,7 @@ |
| 261 | |
| 262 | OBJS = gui.o file.o html.o htmldoc.o htmllib.o htmlsep.o http.o \ |
| 263 | http-addr.o http-support.o image.o iso8859.o license.o md5.o \ |
| 264 | - progress.o ps-pdf.o rc4.o snprintf.o string.o toc.o util.o |
| 265 | + progress.o ps-pdf.o rc4.o snprintf.o string.o toc.o util.o style.o |
| 266 | |
| 267 | |
| 268 | # |
| 269 | |