1 /* File : slides.c 2 Author : Richard A. O'Keefe 3 Updated: 10/13/09 4 Purpose: Convert my format to LaTeX {slides} format. 5 */ 6 #include 7 #include 8 #include 9 #include 10 #include "dvm2.h" 11 extern char *datefmt(char *, size_t, char const *, char const *); 12 13 static int pdf = 0; /* Want to use 'pdflatex'? */ 14 15 static const char unknown[] = "{?`}"; 16 17 static char const *const Char_Map[256] = { 18 unknown, /* CONTROL CHARACTER */ 19 unknown, /* CONTROL CHARACTER */ 20 unknown, /* CONTROL CHARACTER */ 21 unknown, /* CONTROL CHARACTER */ 22 unknown, /* CONTROL CHARACTER */ 23 unknown, /* CONTROL CHARACTER */ 24 unknown, /* CONTROL CHARACTER */ 25 unknown, /* CONTROL CHARACTER */ 26 unknown, /* CONTROL CHARACTER */ 27 " ", /* CONTROL CHARACTER */ 28 "\n", /* CONTROL CHARACTER */ 29 unknown, /* CONTROL CHARACTER */ 30 unknown, /* CONTROL CHARACTER */ 31 unknown, /* CONTROL CHARACTER */ 32 unknown, /* CONTROL CHARACTER */ 33 unknown, /* CONTROL CHARACTER */ 34 unknown, /* CONTROL CHARACTER */ 35 unknown, /* CONTROL CHARACTER */ 36 unknown, /* CONTROL CHARACTER */ 37 unknown, /* CONTROL CHARACTER */ 38 unknown, /* CONTROL CHARACTER */ 39 unknown, /* CONTROL CHARACTER */ 40 unknown, /* CONTROL CHARACTER */ 41 unknown, /* CONTROL CHARACTER */ 42 unknown, /* CONTROL CHARACTER */ 43 unknown, /* CONTROL CHARACTER */ 44 unknown, /* CONTROL CHARACTER */ 45 unknown, /* CONTROL CHARACTER */ 46 unknown, /* CONTROL CHARACTER */ 47 unknown, /* CONTROL CHARACTER */ 48 unknown, /* CONTROL CHARACTER */ 49 unknown, /* CONTROL CHARACTER */ 50 " ", /* */ 51 "{!}", /* !; {} to suppress !` */ 52 "\"", /* " */ 53 "\\#", /* # */ 54 "\\$", /* $ */ 55 "\\%", /* % */ 56 "\\&", /* & */ 57 "{\\tt '}", /* ' */ 58 "(", /* ( */ 59 ")", /* ) */ 60 "{*}", /* *; avoid \* problems */ 61 "+", /* + */ 62 ",", /* , */ 63 "{-}", /* -; avoid -- and --- ligatures */ 64 ".", /* . */ 65 "/", /* / */ 66 "0", /* 0 */ 67 "1", /* 1 */ 68 "2", /* 2 */ 69 "3", /* 3 */ 70 "4", /* 4 */ 71 "5", /* 5 */ 72 "6", /* 6 */ 73 "7", /* 7 */ 74 "8", /* 8 */ 75 "9", /* 9 */ 76 ":", /* : */ 77 ";", /* ; */ 78 "\\ensuremath{<}", /* < */ 79 "=", /* = */ 80 "\\ensuremath{>}", /* > */ 81 "{?}", /* ?; {} to suppress ?` */ 82 "@", /* @ */ 83 "A", /* A */ 84 "B", /* B */ 85 "C", /* C */ 86 "D", /* D */ 87 "E", /* E */ 88 "F", /* F */ 89 "G", /* G */ 90 "H", /* H */ 91 "I", /* I */ 92 "J", /* J */ 93 "K", /* K */ 94 "L", /* L */ 95 "M", /* M */ 96 "N", /* N */ 97 "O", /* O */ 98 "P", /* P */ 99 "Q", /* Q */ 100 "R", /* R */ 101 "S", /* S */ 102 "T", /* T */ 103 "U", /* U */ 104 "V", /* V */ 105 "W", /* W */ 106 "X", /* X */ 107 "Y", /* Y */ 108 "Z", /* Z */ 109 "{[}", /* [; avoid \item problems */ 110 "\\ensuremath{\\backslash}",/* \ */ 111 "{]}", /* ]; avoid \item problems */ 112 "\\textasciicircum", /* ^ */ 113 "\\_", /* _ */ 114 "`", /* ` */ 115 "a", /* a */ 116 "b", /* b */ 117 "c", /* c */ 118 "d", /* d */ 119 "e", /* e */ 120 "f", /* f */ 121 "g", /* g */ 122 "h", /* h */ 123 "i", /* i */ 124 "j", /* j */ 125 "k", /* k */ 126 "l", /* l */ 127 "m", /* m */ 128 "n", /* n */ 129 "o", /* o */ 130 "p", /* p */ 131 "q", /* q */ 132 "r", /* r */ 133 "s", /* s */ 134 "t", /* t */ 135 "u", /* u */ 136 "v", /* v */ 137 "w", /* w */ 138 "x", /* x */ 139 "y", /* y */ 140 "z", /* z */ 141 "\\{", /* { */ 142 "\\ensuremath{|}", /* | */ 143 "\\}", /* } */ 144 "\\ensuremath{\\sim}", /* ~ */ 145 unknown, /* CONTROL CHARACTER */ 146 147 /* Codes 128 to 159 are fakes, used in standard.dtd & slides.dtd */ 148 "\\ensuremath{\\le}", /* 128: le */ 149 "\\ensuremath{\\ge}", /* 129: ge */ 150 "\\ensuremath{\\ne}", /* 130: ne */ 151 "\\ensuremath{'}", /* 131: prime */ 152 "\\hspace{1.0em}", /* 132: emsp */ 153 "\\hspace{0.5em}", /* 133: ensp */ 154 "{---}", /* 134: mdash */ 155 "{--}", /* 135: ndash */ 156 "\\dots{}", /* 136: dots */ 157 "\\ensuremath{\\therefore}",/* 137: there4 */ 158 "{``}", /* 138: ldquo */ 159 "{''}", /* 139: rdquo */ 160 "\\vdots{}", /* 140: vdots */ 161 "d\\,j", /* 141: djlig */ 162 "D\\,j", /* 142: Djlig */ 163 "D\\,J", /* 143: DJlig */ 164 "\\~y", /* 144: ytilde */ 165 "\\ensuremath{\\leftarrow}",/* 145: larr */ 166 "\\ensuremath{\\rightarrow}",/* 146: rarr */ 167 "\\ensuremath{\\uparrow}", /* 147: uarr */ 168 "\\ensuremath{\\downarrow}",/* 148: darr */ 169 170 unknown, /* CONTROL CHARACTER */ 171 172 "\\=A", /* 150: Amacr */ 173 "\\=E", /* 151: Emacr */ 174 "\\=I", /* 152: Imacr */ 175 "\\=O", /* 153: Omacr */ 176 "\\=U", /* 154: Umacr */ 177 "\\=a", /* 155: amacr */ 178 "\\=e", /* 156: emacr */ 179 "\\=i", /* 157: imacr */ 180 "\\=o", /* 158: omacr */ 181 "\\=u", /* 159: umacr */ 182 183 "~", /* 160: no-break space */ 184 "!`", /* inverted exclamation mark */ 185 "/\\kern-.5em{c}", /* cent sign */ 186 "{\\pounds}", /* pound sterling sign */ 187 unknown, /* general currency sign */ 188 "=\\kern-.7em{Y}", /* yen sign */ 189 "\\ensuremath{\\ddagger}", /* broken (vertical) bar [WRONG] */ 190 "{\\S}", /* section sign */ 191 "\\ensuremath{\\ddot{\\texttt{ }}}", /* umlaut (dieresis) */ 192 "{\\copyright}", /* copyright sign */ 193 "\\ensuremath{{}^{\\underline{a}}}", /* ordinal indicator, feminine */ 194 "{\\footnotesize$\\ll$}", /* angle quotation mark, left */ 195 "\\ensuremath{\\neg}", /* not sign */ 196 "\\-", /* soft hyphen */ 197 "(R)", /* registered sign */ 198 "\\ensuremath{\\bar{\\texttt{ }}}", /* macron */ 199 "\\ensuremath{{}^\\circ}", /* degree sign */ 200 "\\ensuremath{\\pm}", /* plus-or-minus sign */ 201 "\\ensuremath{{}^2}", /* superscript two */ 202 "\\ensuremath{{}^3}", /* superscript three */ 203 "\\ensuremath{\\acute{\\texttt{ }}}", /* acute accent */ 204 "\\ensuremath{\\mu}", /* micro sign */ 205 "{\\P}", /* pilcrow (paragraph sign) */ 206 "\\ensuremath{\\cdot}", /* middle dot */ 207 "\\ensuremath{_{,}}", /* cedilla; close but no cigar */ 208 "\\ensuremath{{}^1}", /* superscript one */ 209 "\\ensuremath{{}^{\\underline{o}}}", /* ordinal indicator, masculine */ 210 "{\\footnotesize$\\gg$}",/* angle quotation mark, right */ 211 "\\ensuremath{\\frac{1}{4}}", /* fraction one-quarter */ 212 "\\ensuremath{\\frac{1}{2}}", /* fraction one-half */ 213 "\\ensuremath{\\frac{3}{4}}", /* fraction three-quarters */ 214 "?`", /* inverted question mark */ 215 "\\`{A}", /* capital A, grave accent */ 216 "\\'{A}", /* capital A, acute accent */ 217 "\\^{A}", /* capital A, circumflex accent */ 218 "\\~{A}", /* capital A, tilde */ 219 "\\\"{A}", /* capital A, dieresis or umlaut mark */ 220 "{\\AA}", /* capital A, ring */ 221 "{\\AE}", /* capital AE diphthong (ligature) */ 222 "\\c{C}", /* capital C, cedilla */ 223 "\\`{E}", /* capital E, grave accent */ 224 "\\'{E}", /* capital E, acute accent */ 225 "\\^{E}", /* capital E, circumflex accent */ 226 "\\\"{E}", /* capital E, dieresis or umlaut mark */ 227 "\\`{I}", /* capital I, grave accent */ 228 "\\'{I}", /* capital I, acute accent */ 229 "\\^{I}", /* capital I, circumflex accent */ 230 "\\\"{I}", /* capital I, dieresis or umlaut mark */ 231 "{Dh}", /* capital Eth, Icelandic; WRONG */ 232 "\\~{N}", /* capital N, tilde */ 233 "\\`{O}", /* capital O, grave accent */ 234 "\\'{O}", /* capital O, acute accent */ 235 "\\^{O}", /* capital O, circumflex accent */ 236 "\\~{O}", /* capital O, tilde */ 237 "\\\"{O}", /* capital O, dieresis or umlaut mark */ 238 "\\ensuremath{\\times}", /* multiply sign */ 239 "{\\O}", /* capital O, slash */ 240 "\\`{U}", /* capital U, grave accent */ 241 "\\'{U}", /* capital U, acute accent */ 242 "\\^{U}", /* capital U, circumflex accent */ 243 "\\\"{U}", /* capital U, dieresis or umlaut mark */ 244 "\\'{Y}", /* capital Y, acute accent */ 245 "{Th}", /* capital THORN, Icelandic; WRONG */ 246 "{\\ss}", /* small sharp s, German (sz ligature) */ 247 "\\`{a}", /* small a, grave accent */ 248 "\\'{a}", /* small a, acute accent */ 249 "\\^{a}", /* small a, circumflex accent */ 250 "\\~{a}", /* small a, tilde */ 251 "\\\"{a}", /* small a, dieresis or umlaut mark */ 252 "{\\aa}", /* small a, ring */ 253 "{\\ae}", /* small ae diphthong (ligature) */ 254 "\\c{c}", /* small c, cedilla */ 255 "\\`{e}", /* small e, grave accent */ 256 "\\'{e}", /* small e, acute accent */ 257 "\\^{e}", /* small e, circumflex accent */ 258 "\\\"{e}", /* small e, dieresis or umlaut mark */ 259 "\\`{\\i}", /* small i, grave accent */ 260 "\\'{\\i}", /* small i, acute accent */ 261 "\\^{\\i}", /* small i, circumflex accent */ 262 "\\\"{\\i}", /* small i, dieresis or umlaut mark */ 263 "{dh}", /* small eth, Icelandic; WRONG */ 264 "\\~{n}", /* small n, tilde */ 265 "\\`{o}", /* small o, grave accent */ 266 "\\'{o}", /* small o, acute accent */ 267 "\\^{o}", /* small o, circumflex accent */ 268 "\\~{o}", /* small o, tilde */ 269 "\\\"{o}", /* small o, dieresis or umlaut mark */ 270 "\\ensuremath{\\div}", /* divide sign */ 271 "{\\o}", /* small o, slash */ 272 "\\`{u}", /* small u, grave accent */ 273 "\\'{u}", /* small u, acute accent */ 274 "\\^{u}", /* small u, circumflex accent */ 275 "\\\"{u}", /* small u, dieresis or umlaut mark */ 276 "\\'{y}", /* small y, acute accent */ 277 "{th}", /* small thorn, Icelandic; WRONG */ 278 "\\\"{y}", /* small y, dieresis or umlaut mark */ 279 }; 280 281 #define LATEX_SQUISH_NOTHING 0 282 #define LATEX_SQUISH_NEWLINES 1 283 #define LATEX_SQUISH_LAYOUT 3 284 #define LATEX_DUMB_QUOTES 0 285 #define LATEX_SMART_QUOTES 4 286 287 void print_as_latex(char const *s, int options) { 288 register FILE *f = stdout; 289 register unsigned char const *x = (unsigned char const *)s; 290 register unsigned char c; 291 292 if ((options & LATEX_SMART_QUOTES) != 0) { 293 char const *m; 294 while ((c = *x++) != '\0') { 295 switch (options & LATEX_SQUISH_LAYOUT) { 296 case LATEX_SQUISH_NOTHING: 297 break; 298 case LATEX_SQUISH_NEWLINES: 299 if (c == '\n') while (*x == c) x++; 300 break; 301 case LATEX_SQUISH_LAYOUT: 302 if (c <= ' ') { 303 while ((c = *x) <= ' ' && c != '\0') x++; 304 putc(' ', f); 305 continue; 306 } 307 break; 308 } 309 switch (c) { 310 case '\'': 311 m = x-1 == (unsigned char const *)s 312 || strchr("{[( \t\n", x[-2]) != 0 313 ? "{`}" : "{'}"; 314 break; 315 case '\"': 316 m = x-1 == (unsigned char const *)s 317 || strchr("{[( \t\n", x[-2]) != 0 318 ? "{``}" : "{''}"; 319 break; 320 default: 321 m = Char_Map[c]; 322 break; 323 } 324 fputs(m, f); 325 } 326 } else 327 if ((options & LATEX_SQUISH_LAYOUT) == 0) { 328 while ((c = *x++) != '\0') fputs(Char_Map[c], f); 329 } else 330 if ((options & LATEX_SQUISH_LAYOUT) == LATEX_SQUISH_NEWLINES) { 331 while ((c = *x++) != '\0') { 332 if (c == '\n') while (*x == c) x++; 333 fputs(Char_Map[c], f); 334 } 335 } else { 336 while ((c = *x++) != '\0') { 337 if (c <= ' ') { 338 while ((c = *x) <= ' ' && c != '\0') x++; 339 putc(' ', f); 340 } else { 341 fputs(Char_Map[c], f); 342 } 343 } 344 } 345 } 346 347 void unexpected(xml e0) { 348 if (is_pcdata(e0)) { 349 fprintf(stderr, "Unexpected text: %s\n", text_of(e0)); 350 } else 351 if (is_pi(e0)) { 352 fprintf(stderr, "Unexpected processing instruction: %s\n", 353 text_of(pi_target(e0))); 354 } else 355 if (is_element(e0)) { 356 fprintf(stderr, "Unexpected element: %s\n", element_name(e0)); 357 } else { 358 fprintf(stderr, "Unexpected unknown\n"); 359 } 360 abort(); 361 } 362 363 void walk_maths(char const *before, xml e0, char const *after) { 364 fputs(before, stdout); 365 for_each_child(e0, i, e1) 366 if (is_pcdata(e1)) { 367 print_as_latex(text_of(e1), LATEX_SQUISH_LAYOUT); 368 } else 369 if (is_element_named(e1, "SUB")) { 370 walk_maths("_{", e1, "}"); 371 } else 372 if (is_element_named(e1, "SUP")) { 373 walk_maths("^{", e1, "}"); 374 } else 375 if (is_element_named(e1, "ROMAN")) { 376 walk_maths("{\\mathrm ", e1, "}"); 377 } else 378 if (is_element_named(e1, "MATRIX")) { 379 printf("\\fbox{MATRIX}"); 380 } else { 381 unexpected(e1); 382 } 383 end_each_child 384 fputs(after, stdout); 385 } 386 387 void walk_paragraph(char const *before, xml e0, char const *after) { 388 fputs(before, stdout); 389 for_each_child(e0, i, e1) 390 if (is_pcdata(e1)) { 391 print_as_latex(text_of(e1), LATEX_SQUISH_LAYOUT); 392 } else 393 if (is_element_named(e1, "b")) { 394 walk_paragraph("\\textbf{", e1, "}"); 395 } else 396 if (is_element_named(e1, "i")) { 397 walk_paragraph("\\textit{", e1, "}"); 398 } else 399 if (is_element_named(e1, "f") /* file */ 400 || is_element_named(e1, "u") /* url */ 401 ) { 402 unsigned char c; 403 unsigned char const *s = 404 (unsigned char const *)text_of(pcdata_text(e1)); 405 unsigned char const *p = s; 406 407 while ((c = *p++) != 0) 408 fputs(c == '/' && p != s+1 && *p != '\0' 409 ? "\\slash " : Char_Map[c], stdout); 410 } else 411 if (is_element_named(e1, "t")) { 412 walk_paragraph("\\texttt{", e1, "}"); 413 } else 414 if (is_element_named(e1, "m")) { 415 walk_maths("\\(", e1, "\\)"); 416 } else 417 if (is_element_named(e1, "big")) { 418 walk_paragraph("{\\large ", e1, "}"); 419 } else 420 if (is_element_named(e1, "small")) { 421 walk_paragraph("{\\small ", e1, "}"); 422 } else 423 if (is_element_named(e1, "q") 424 || is_element_named(e1, "quoted") 425 ) { 426 static int qflag = 0; 427 428 qflag = 1 - qflag; 429 if (qflag == 0) { 430 walk_paragraph("{`}", e1, "{'}"); 431 } else { 432 walk_paragraph("{``}", e1, "{''}"); 433 } 434 qflag = 1 - qflag; 435 } else 436 if (is_element_named(e1, "source")) { 437 walk_paragraph("\\hfill{---} ", e1, ""); 438 } else 439 if (is_element_named(e1, "br")) { 440 /*
makes sense but is not implemented yet */ 441 char const *amount = value(e1, "i", (char*)0); 442 char const *strong = value(e1, "strength", (char *)0); 443 unsigned char c; 444 445 if (strong != 0) { 446 printf("\\linebreak[%s]", strong); 447 } else { 448 fputs("\\\\\n", stdout); 449 if (amount != 0) { 450 fputs("{\\hglue ", stdout); 451 while ((c = *(unsigned char*)(amount++)) != '\0') 452 putc(tolower(c), stdout); 453 fputs("}", stdout); 454 } 455 } 456 } else 457 if (is_element_named(e1, "name") 458 || is_element_named(e1, "acr") 459 ) { 460 walk_paragraph("", e1, ""); 461 } else 462 if (is_element_named(e1, "hack")) { 463 fputs(value(e1, "tex", ""), stdout); 464 } else { 465 unexpected(e1); 466 } 467 end_each_child 468 fputs(after, stdout); 469 } 470 471 void walk_list(xml e0, int depth) { 472 int labelled = 0; 473 int counter = 0; 474 char const *ty = value(e0, "TYPE", "N"); 475 enum {N, AU, AL, RU, RL, ARROW, AST, BULLET, CIRCLE, DASH} type = 476 0 == strcmp(ty, "N") ? N : 477 0 == strcmp(ty, "AU") ? AU : 478 0 == strcmp(ty, "AL") ? AL : 479 0 == strcmp(ty, "RU") ? RU : 480 0 == strcmp(ty, "RL") ? RL : 481 0 == strcmp(ty, "ARROW") ? ARROW : 482 0 == strcmp(ty, "AST") ? AST : 483 0 == strcmp(ty, "BULLET") ? BULLET : 484 0 == strcmp(ty, "CIRCLE") ? CIRCLE : 485 0 == strcmp(ty, "DASH") ? DASH : 486 /* default if not known */ N; 487 488 for_each_element_child(e0, i, j, e1) 489 if (is_element_named(e1, "label")) { 490 printf("\\par\\noindent\\hspace*{%dem}", 2*depth); 491 walk_paragraph("{\\bf ", e1, "}"); 492 labelled = 1; 493 } else 494 if (is_element_named(e1, "item")) { 495 char const *gap = value(e1, "gap", (char*)0); 496 497 if (gap == (char*)0) { 498 if (!labelled) { 499 printf("\\par\\noindent\\hspace*{%dem}", 2*depth); 500 counter++; 501 switch (type) { 502 case N: 503 printf("%d.", counter); 504 break; 505 case AU: case RU: /* RU not finished */ 506 printf("%c.", 'A'-1 + counter); 507 break; 508 case AL: case RL: /* RL not finished */ 509 printf("%c.", 'a'-1 + counter); 510 break; 511 case ARROW: 512 printf("$\\rightarrow$"); break; 513 case AST: 514 printf("$\\ast$"); break; 515 case BULLET: 516 printf("$\\bullet$"); break; 517 case CIRCLE: 518 printf("$\\circ$"); break; 519 case DASH: 520 printf("{---}"); break; 521 } 522 } 523 walk_paragraph(" ", e1, "\n"); 524 } else { 525 fputs("\\rule{0mm}{\\baselineskip}\n", stdout); 526 } 527 labelled = 0; 528 } else 529 if (is_element_named(e1, "list")) { 530 walk_list(e1, depth+1); 531 } else { 532 unexpected(e1); 533 } 534 end_each_element_child 535 } 536 537 void walk_table(xml e0) { 538 int border = value(e0, "border", 0) != 0; 539 int rflag, cflag; 540 xml e1 = first_child_named(e0, "tr"); 541 char const *a = value(e0, "align", "l"); 542 char const *p = a; 543 /* align should match /[lrcd]+/; it's recycled as needed. */ 544 545 printf("\\begin{tabular}{%s", border ? "|" : ""); 546 if (e1 == 0) { 547 fprintf(stderr, " element with no child.\n"); 548 exit(EXIT_FAILURE); 549 } 550 for_each_named_child(e1, i, "td", j, e2) 551 putchar(*p); 552 if (*++p == '\0') p = a; 553 end_each_named_child 554 printf("%s}\n", border ? "|" : ""); 555 556 rflag = border; 557 if (rflag) printf("\\hline"); 558 for_each_element_child(e0, i, j, e1) 559 printf(rflag ? "\\\\\n" : "\n"); 560 rflag = 1; 561 cflag = 0; 562 for_each_element_child(e1, k, l, e2) 563 if (cflag) printf(" & "); 564 cflag = 1; 565 walk_paragraph("", e2, ""); 566 end_each_element_child 567 end_each_element_child 568 if (border) printf("\\\\\\hline"); 569 printf("\n\\end{tabular}\n"); 570 } 571 572 void walk_slide_or_notes(xml e0) { 573 int labelled = 0; 574 575 for_each_element_child(e0, i, j, e1) 576 if (is_element_named(e1, "title")) { 577 walk_paragraph("\\begin{center}\\Large ", e1, "\\end{center}\n"); 578 } else 579 if (is_element_named(e1, "label")) { 580 walk_paragraph("\\par\\noindent {\\bf ", e1, "} "); 581 labelled = 1; 582 } else 583 if (is_element_named(e1, "item")) { 584 char const *gap = value(e1, "gap", (char*)0); 585 char const *ty = value(e1, "type", "N"); 586 enum {N, ARROW, AST, BULLET, CIRCLE, DASH} type = 587 0 == strcmp(ty, "N") ? N : 588 0 == strcmp(ty, "ARROW") ? ARROW : 589 0 == strcmp(ty, "AST") ? AST : 590 0 == strcmp(ty, "BULLET") ? BULLET : 591 0 == strcmp(ty, "CIRCLE") ? CIRCLE : 592 0 == strcmp(ty, "DASH") ? DASH : 593 /* default if not known */ N; 594 595 if (gap == (char*)0) { 596 if (!labelled) fputs("\\par\\noindent ", stdout); 597 switch (type) { 598 case N: 599 break; 600 case ARROW: 601 printf("$\\rightarrow$ "); break; 602 case AST: 603 printf("$\\ast$ "); break; 604 case BULLET: 605 printf("$\\bullet$ "); break; 606 case CIRCLE: 607 printf("$\\circ$ "); break; 608 case DASH: 609 printf("{---} "); break; 610 } 611 walk_paragraph("", e1, "\n"); 612 } else { 613 fputs("\\rule{0mm}{\\baselineskip}\n", stdout); 614 } 615 labelled = 0; 616 } else 617 if (is_element_named(e1, "p") 618 || is_element_named(e1, "quote") 619 ) { 620 char *start = has_value(e1, "cont", "CONT") 621 ? "\\par\\noindent " : "\\par "; 622 walk_paragraph(start, e1, "\n"); 623 } else 624 if (is_element_named(e1, "table")) { 625 walk_table(e1); 626 } else 627 if (is_element_named(e1, "pre")) { 628 /* I would like this to handle and */ 629 fputs("\\begin{verbatim}\n", stdout); 630 for_each_text_descendant(e1, e2) 631 fputs(text_of(e2), stdout); 632 end_each_text_descendant 633 fputs("\n\\end{verbatim}\n", stdout); 634 } else 635 if (is_element_named(e1, "list")) { 636 walk_list(e1, 0); 637 } else { 638 unexpected(e1); 639 } 640 end_each_element_child 641 } 642 643 void walk_slide(xml e0) { 644 fputs("\\begin{slide}\n", stdout); 645 walk_slide_or_notes(e0); 646 fputs("\\end{slide}\n", stdout); 647 } 648 649 void do_slides(xml e0) { 650 char const *paper = value(e0, "paper", "[paper]"); 651 char const *week = value(e0, "week", "[week]"); 652 char const *date = value(e0, "date", "[date]"); 653 654 puts("\\documentclass[a4paper,landscape,draft]{slides}"); 655 puts("\\usepackage{amssymb}"); 656 if (pdf) { 657 puts("\\usepackage[pdftex]{geometry}"); 658 puts("\\geometry{headsep=2.0em,hscale=0.80}"); 659 } 660 puts("\\begin{document}"); 661 puts("\\begin{slide}"); 662 puts("\\begin{center}"); 663 printf("{\\Large %s Week %s}\n\n", paper, week); 664 665 for_each_element_child(e0, i, j, e1) 666 if (is_element_named(e1, "slide")) { 667 walk_slide(e1); 668 } else 669 if (is_element_named(e1, "title")) { 670 char datebuf[32]; 671 char *d = datefmt(datebuf, sizeof datebuf, "%e %B %Y", date); 672 673 walk_paragraph("{\\Large ", e1, "}\n\n"); 674 printf("{\\Large %s}\n\n", d == 0 ? date : d); 675 } else 676 if (is_element_named(e1, "lecturer")) { 677 walk_paragraph("{\\normalsize ", e1, "}\n\n"); 678 puts("\\end{center}"); 679 puts("\\end{slide}"); 680 } else 681 if (!is_element_named(e1, "notes")) { 682 unexpected(e1); 683 } 684 end_each_element_child 685 puts("\\end{document}"); 686 } 687 688 void do_notes(xml e0) { 689 char const *paper = value(e0, "paper", "[paper]"); 690 char const *week = value(e0, "week", "[week]"); 691 692 puts("\\documentclass[a4paper,draft]{article}"); 693 puts("\\usepackage{amssymb}"); 694 puts("\\begin{document}"); 695 puts("\\begin{center}"); 696 printf("{\\Large %s Week %s Notes}\n\n", paper, week); 697 puts("\\end{center}"); 698 699 for_each_element_child(e0, i, j, e1) 700 if (is_element_named(e1, "notes")) { 701 walk_slide_or_notes(e1); 702 } else 703 if (!is_element_named(e1, "slide") 704 && !is_element_named(e1, "title") 705 && !is_element_named(e1, "lecturer") 706 ) { 707 unexpected(e1); 708 } 709 end_each_element_child 710 puts("\\end{document}"); 711 } 712 713 int main(int argc, char **argv) { 714 if (argc > 1 && 0 == memcmp("-p", argv[1], 2)) { /* -Pdf */ 715 pdf = 1; 716 argc--, argv++; 717 } 718 if (argc > 1 && 0 == memcmp("-n", argv[1], 2)) { /* -Notes */ 719 argc--, argv++; 720 do_notes(first_child_named(load_esis_through(stdin, 0), "slides")); 721 } else { 722 do_slides(first_child_named(load_esis_through(stdin, 0), "slides")); 723 } 724 return 0; 725 } 726