/* pptHtml - Format a PowerPoint Presentation into Html Copyright 2002 Charles N Wyble This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #if !(defined( __BORLANDC__ ) || defined( __WIN32__ )) #include "config.h" /* Created by ./configure script */ #include "support.h" /* Needs to be before internal.h */ #include "internal.h" /* Needs to be before cole */ #include "cole.h" #else #include "config.h.in" /* Created by ./configure script */ #include "support.h" /* Needs to be before internal.h */ #include "internal.h" /* Needs to be before cole */ #include "cole.h.in" #include #endif #include #include /* for strcpy() */ #include /* For isprint */ #include /* For exitt() */ #define PRGNAME "pptHtml" #if !(defined( __WIN32__ ) || defined( __BORLANDC__ )) #define PRGVER VERSION #else #define PRGVER "0.4" #endif #define WORK_SIZE 8192 static char FileName[2][32] = /* The section of the PowerPoint File we read */ { "/PowerPoint Document", /* Power Point 97 & 2000 */ "/PP40" /* Everything else ? */ }; /* Function Prototypes */ COLE_LOCATE_ACTION_FUNC dump_file; static void container_processor(int); static void atom_processor(int, int, int, unsigned char); static void print_unicode(unsigned char *, int); static void print_utf8(unsigned short c); static void put_utf8(unsigned short c); /* Global data */ static char filename[128]; static unsigned char working_buffer[WORK_SIZE]; static int buf_idx=0; static int output_this_container = 0; static int past_first_slide = 0; static int last_container = 0; int main (int argc, char **argv) { int f_ptr = 0; COLEFS * cfs; COLERRNO colerrno; if (argc < 2) { fprintf (stderr, "pptHtml - Outputs Power Point files as Html.\n" "Usage: "PRGNAME" \n"); exit (1); } else { strncpy(filename, argv[1], 124); #if defined( __WIN32__ ) || defined( __BORLANDC__ ) { char *ptr = strchr(filename, ':'); if (ptr) { int len; char new_drive[MAXPATH]; fnsplit(filename, new_drive, 0, 0, 0); if (new_drive[0] >= 'a') setdisk(new_drive[0] - 'a'); else setdisk(new_drive[0] - 'A'); ptr++; /* Get past the colon */ len = strlen(ptr); memmove(filename, ptr, len); filename[len] = 0; } } #endif cfs = cole_mount (filename, &colerrno); if (cfs == NULL) { cole_perror (PRGNAME, colerrno); exit (1); } } while (cole_locate_filename (cfs, FileName[f_ptr], NULL, dump_file, &colerrno)) { if (f_ptr) { /* Two strikes...we're out! */ cole_perror (PRGNAME, colerrno); if (colerrno == COLE_EFILENOTFOUND) fprintf(stderr, "Section: PowerPoint Document\n"); break; } else /* Don't do this... */ f_ptr++; } if (cole_umount (cfs, &colerrno)) { cole_perror ("travel", colerrno); exit (1); } return 0; } void dump_file(COLEDIRENT *cde, void *_info) { unsigned long version=0, instance=0, type=0, length=0, target=0, count=0; unsigned char buf[16]; COLEFILE *cf; COLERRNO err; cf = cole_fopen_direntry(cde, &err); /* Ouput Header */ printf("\n"); printf("%s", filename); printf("\n"); /* Output body */ while (cole_fread(cf, buf, 1, &err)) { if (count == 0) { instance = buf[0]; type = 0; length = 0; target = 80; /* ficticious number */ } else if (count == 1) { instance |= (buf[0]<<8); version = instance &0x000F; instance = (instance>>4); } else if (count == 2) type = (unsigned)buf[0]; else if (count == 3) type |= (buf[0]<<8)&0x00000FFFL; else if (count == 4) length = (unsigned)buf[0]; else if (count == 5) length |= (buf[0]<<8); else if (count == 6) length |= (buf[0]<<16); else if (count == 7) { length |= (buf[0]<<24); target = length; if (version == 0x0F) { /* Do container level Processing */ container_processor(type); count = -1; } } if (count > 7) { /* Here is where we want to process the data based on the Atom type... */ atom_processor(type, count-8, target-1, buf[0]); } if (count == (target+7)) count = 0; else count++; } if (past_first_slide) printf("
"); printf(" 
\n"); /* Output Credit */ printf("
Created with pptHtml
\n" ); /* Output Tail */ printf("\n"); cole_fclose(cf, &err); } static void container_processor(int type) { if (type == 0x03EE) { if (past_first_slide) printf("


\n"); else past_first_slide = 1; } switch (type) { case 0x000D: if (last_container == 0x11) /* suppress notes info */ output_this_container = 0; else output_this_container = 1; break; case 0x0FF0: output_this_container = 1; break; default: /* printf("Cont:%x|\n", type); */ output_this_container = 0; break; } last_container = type; } static void atom_processor(int type, int count, int buf_last, unsigned char data) { if ((buf_idx >= WORK_SIZE)||(output_this_container == 0)) return; if (count == 0) { memset(working_buffer, 0, WORK_SIZE); buf_idx = 0; } switch (type) { case 0x0FA0: /* Text String in unicode */ working_buffer[buf_idx++] = data; if (count == buf_last) { /* printf("Atom:%x|\n", type); */ /* working_buffer[buf_idx++] = 0; */ /* printf("%s
\n", working_buffer); */ print_unicode(working_buffer, buf_idx); printf("
\n"); } break; case 0x0FA8: /* Text String in ASCII */ working_buffer[buf_idx++] = data; if (count == buf_last) { int i; /* working_buffer[buf_idx++] = 0; */ /* printf("Atom:%x|\n", type); */ for (i=0;i\n"); else putchar(working_buffer[i]); } printf("
\n"); } break; case 0x0FBA: /* CString - unicode... */ working_buffer[buf_idx++] = data; if (count == buf_last) { /* working_buffer[buf_idx++] = 0; */ /* printf("%s
\n", working_buffer); */ /* printf("Atom:%x|\n", type); */ print_unicode(working_buffer, buf_idx); printf("
\n"); } break; default: break; } } static void print_unicode(unsigned char *ucs, int len) { int i; for (i = 0; i < len; i += 2) print_utf8(ucs[i] | (ucs[i+1] << 8)); } static void OutputCharCorrected(unsigned char c) { switch (c) { /* Special char handlers here... */ case '\r': printf("
\n"); break; case 0x3C: printf("<"); break; case 0x3E: printf(">"); break; case 0x26: printf("&"); break; case 0x22: printf("""); break; /* Also need to cover 128-159 since MS uses this area... */ case 0x80: /* Euro Symbol */ printf("€"); break; case 0x82: /* baseline single quote */ printf("‚"); break; case 0x83: /* florin */ printf("ƒ"); break; case 0x84: /* baseline double quote */ printf("„"); break; case 0x85: /* ellipsis */ printf("…"); break; case 0x86: /* dagger */ printf("†"); break; case 0x87: /* double dagger */ printf("‡"); break; case 0x88: /* circumflex accent */ printf("ˆ"); break; case 0x89: /* permile */ printf("‰"); break; case 0x8A: /* S Hacek */ printf("Š"); break; case 0x8B: /* left single guillemet */ printf("‹"); break; case 0x8C: /* OE ligature */ printf("Œ"); break; case 0x8E: /* #LATIN CAPITAL LETTER Z WITH CARON */ printf("Ž"); break; case 0x91: /* left single quote ? */ printf("‘"); break; case 0x92: /* right single quote ? */ printf("’"); break; case 0x93: /* left double quote */ printf("“"); break; case 0x94: /* right double quote */ printf("”"); break; case 0x95: /* bullet */ printf("•"); break; case 0x96: /* endash */ printf("–"); break; case 0x97: /* emdash */ printf("—"); break; case 0x98: /* tilde accent */ printf("˜"); break; case 0x99: /* trademark ligature */ printf("™"); break; case 0x9A: /* s Haceks Hacek */ printf("š"); break; case 0x9B: /* right single guillemet */ printf("›"); break; case 0x9C: /* oe ligature */ printf("œ"); break; case 0x9F: /* Y Dieresis */ printf("Ÿ"); break; default: putchar(c); break; } } static void print_utf8(unsigned short c) { if (c == 0) return; if (c < 0x80) OutputCharCorrected(c); else if (c < 0x800) { putchar(0xC0 | (c >> 6)); put_utf8(c); } else { putchar(0xE0 | (c >> 12)); put_utf8(c >> 6); put_utf8(c); } } static void put_utf8(unsigned short c) { putchar(0x0080 | ((short)c & 0x003F)); }