From: SMTP%"VMSSERV@kcl.ac.uk" 19-AUG-1996 18:18:16.58 To: everhart@star.zko.dec.com CC: Subj: WEBBOOK.4-OF-5 -+-+-+-+-+-+-+-+ START OF PART 4 -+-+-+-+-+-+-+-+ X struct `7B X`09BKREC_COMMON_HEADER`09`09/* type = \1F06FDX */ X`09char txt`5B255`5D; X `7D fdesc; X X struct `7B`09`09&0209/* Font data */ X`09BKREC_COMMON_HEADER`09`09/* type = \1F06FONT */ X `7D font; X X struct `7B X`09BKREC_COMMON_HEADER X`09short flags; X`09long prev, next; X `7D cont;`09`09&0209/* type = BKREC_CONT_* */ X /* X * Sub-record types. X */ X struct `7B`20 X`09BKREC_COMMON_HEADER X`09long unknown0;`09`09`09/* total record size */ X`09unsigned char keyid;`09`09/* 5=contents, 10=index, 0=other */ X`09long count;`09`09`09/*\0C06 of entries */ X`09long part;`09`09`09/* part number */ X`09unsigned char tit_len;`09`09/* length of title string */ X`09char title`5B255`5D; X `7D table;`09`09&0209/* type = BKSBREC_TABLE */ X X struct `7B`09`09&0209/* Font mapping defintion */ X`09BKREC_COMMON_HEADER X`09unsigned short fontno;`09`09/* internal number */ X`09char name`5B255`5D;`09`09`09/* Name asciiz */ X `7D fontdef;`09`09&0209/* type = BKSBREC_FONT */ X X struct `7B X`09BKREC_COMMON_HEADER X`09unsigned short ixhdr`5B7`5D; X`09/* struct text_rec ixtxt; */ X `7D ixtxt;`09`09&0209/* type = BKSBREC_TABLE */ X X struct `7B X`09BKREC_COMMON_HEADER X`09long bodhdr`5B1`5D;`09`09`09/* bodhr`5B0`5D unknown */ X`09long sect_id;`09`09`09/* section id */ X`09long bodhdr2`5B7`5D; X`09/* struct text_rec bodtxt;*/ `09/* varying number */ X `7D bodytext;`09`09&0209/* type = BKSBREC_BODY */ X X struct `7B X`09BKREC_COMMON_HEADER X`09long unk1, unk2; X`09long sect, pos, verpos, len, sect_id, target; X`09long unk3; X `7D hotspot; X X struct `7B X`09BKREC_COMMON_HEADER X`09 long unk1, unk2, sect, x, y, w, h, unk3, unk4; X `7D extension;`09`09/*\0F0A grayspot on body */ X X struct `7B X`09BKREC_COMMON_HEADER X`09char name`5B255`5D;`09`09/* no first page */ X `7D license; X X struct `7B X`09BKREC_COMMON_HEADER X`09 long unk1, unk2; X`09 long sect, x, y, w, h; X`09 long picbytes; X`09 unsigned char primitive, unk5, unk6, unk7; X `09 unsigned short col, rows;`09`09/* col is fontno for txt */ X`09 char var_data`5B1024`5D; X`09`09 `20 X `7D figure; X X`7D; Xtypedef union bkrdr_rec *\0B09ptr; X#ifdef __DECC X#pragma member_alignment X#endif $ call unpack [.WEBBOOK]BOOKREADER_RECDEF.H;1 - 1986655782 "FORMAT STREAM_LF;CARRIAGE_CONTROL CARRIAGE_RETURN" 17 14 20 $! $ create 'f' X$ EXEDIR = "`5B-.system`5D X$ BINDIR = "`5B-.bin`5D X$ CC /NOLIST/OBJECT=WEBBOOK.OBJ webbook.c X$ CC /NOLIST/OBJECT=CGILIB.OBJ cgilib.c X$ CC /NOLIST/OBJECT=SCRIPTLIB.OBJ scriptlib.c X$ CC /NOLIST/OBJECT=BOOKFILE_SECTION.OBJ bookfile_section.c X$ CC /NOLIST/OBJECT=BOOKFILE_INDEX.OBJ bookfile_index.c X$ CC /NOLIST/OBJECT=BOOKFILE_TEXT.OBJ bookfile_text.c X$ CC /NOLIST/OBJECT=BOOKFILE_IO.OBJ bookfile_io.c X$ CC /NOLIST/OBJECT=BOOKFILE_FIGURE.OBJ bookfile_figure.c X$ IF F$GETSYI("CPU") .GE. 128 .OR. F$TRNLNM("DECC$CC_DEFAULT") .EQS. "/DECC" V `09THEN prefix_all = "/\0F06=all" X$ CC webbook_shelf.c 'prefix_all' X$ @link_script webbook/opt,cgilib.obj,\1E06\0E07 X$ COPY webbook.exe 'BINDIR' $ call unpack [.WEBBOOK]BUILD_WEBBOOK.COM;1 - 1983715475 "FORMAT STREAM_LF;CARRIAGE_CONTROL CARRIAGE_RETURN" 2 15 20 $! $ create 'f' X/* X * Bookreader to HTML comverter usage: X * X * path-info: X *`09/dir/file.`5BPnnn.`7CItable.`7CGnnn.`5Dtype`09(type = decw$book) X *`09/hist1`5B/histn...`5D/disk:file.type/ `09(type = decw$bookshelf) X * X * The middle element (`5BPnn.`7CItable...`5C`5D) speficies a sub-section of V X * the file to format: X * X * Pnnn`09Returns part indicated by nnn, which is a decimal number. X * \0806The part number is an internal addressing scheme used by X *`09`09the bookreader to reference a chunk to data to be read at X *`09`09one time. X * X *`09 Itable Format index named by 'table', name is case sensitive and X *`09`09the list of available tables is defined by the document. X * X *`09Gnnn`09Format part nnn as graphic image (GIF). X * X * When the path-info ends in a slash, webbook assumes the preceding X * path element is a VMS file specification of a shelf file to X * format and display. Path element preceding the file name are X * formatted as header lines in the resulting HTML. X * X * Conditional compilation symbols: X *`09NOCGILIB`09When defined, build script for DCL-based CGI X *`09`09`09environment: argv`5B1`5D is path, CGI variables are X *`09`09`09DCL symbols/logicals of form WWW_var_name. X * X *`09VERBOSE`09`09When defined, include bookreader internal codes X *`09`09`09as HTML comments and 'glue' bytes as . X * `20 X * Author:`09David Jones X * Date:`095-MAY-1996 X */ X#include X#include X#include X#include X#include X#ifdef __DECC X#ifndef shell$translate_vms`09`09/* pre 5.0 on VAX */ Xint decc$to_vms(); X#endif X#define SHELL_TO_VMS(a,b,c) decc$to_vms\1306,0)`09/* set no-directory*/ X#else X#define SHELL_TO_VMS shell$to_vms Xint shell$to_vms(); X#endif X X#ifdef NOCGILIB X#define file_arg argv`5B1`5D X#define cgi_init(a,b) 1 X#define cgi_printf \0706 X#define cgi_info(a) getenv(strcpy(`26\1C08_buf`5B4`5D,a)-4) Xstatic char cgi_info_buf`5B64`5D = `7B 'W', 'W',\0A07_' `7D; X#else X#include "scriptlib.h" X#include "cgilib.h" X#define printf cgi_\0B06xxx X#define file_arg cgi_info("PATH_INFO") X#endif X X#include "bookreader_recdef.h" X#include "bookfile_io.h" X#include "bookfile_index.h" X#include "bookfile_section.h" X#include "bookfile_text.h" X#include "bookfile_figure.h" X Xstatic char *webbook_version = "WEBBOOK 0.82, 7-MAY-1995"; X Xstatic int show_part ( void * bkf, int part_num, bktxt_fntptr fontde\2407); Xstatic int show_image ( void *bkf,\1C06ect_num ); X Xstatic char *href_fname; Xstatic char *href_type;`09`09`09/* for genrating HREF="name.xxx.type"*/ Xstatic char *escape_string (\1607source ); Xstatic char vms_bookfile`5B256`5D; Xstatic int save_bookfile_name ( char *name, int flags ) X`7B strncpy ( vms_bookfile, name, 255 );\1B0D`5B255`5D = '`5C0'; return 1; `7D V Xstatic char nbsp = 160;`09`09/* non-breaking space */ X Xstatic void error_abort ( char *sts_line,\1007message ) X`7B X cgi_printf ( "Content-type: text/plain`5Cn%s`5Cn\0606", sts_line, message V ); X exit ( 1 ); X`7D X Xstatic char *entify (\0F07source ) X`7B X int i; char *p, *d; X static char fixup`5B8192`5D; X for ( p = source; *p; p++ ) if ( *p == '<' `7C`7C\0D08>\0D0C`26' ) `7B X`09for ( i = 0, p = source; *p; p++ ) `7B X`09 if ( *p == '<' ) `7B X`09`09strcpy ( `26fixup`5Bi`5D, "`26lt;" ); i += 4; X`09 `7D else if ( *p == '>' ) `7B X`09`09strcpy ( `26fixup`5Bi`5D, "`26gt;" ); i += 4; X`09 `7D else if ( *p == '`26' ) `7B X`09`09strcpy ( `26fixup`5Bi`5D, "`26amp;" ); i += 5; X`09 `7D else fixup`5Bi++`5D = *p; X`09`7D X`09if ( i > 8184 ) return source;`09/* give up */ X`09fixup`5Bi`5D = '`5C0'; X`09return fixup; X `7D X return source;`09/* string OK as is. */ X`7D X Xint webbook_shelf ( char *,\0807 ); X Xint main ( int argc, char **argv ) X`7B X long ndx_value; X int i, j, bad, status, part_length, \0808single_sect\2207num; X int first, ndx_type\0A06count, iter\0C08font\1808select, type; X int dir_delim; X short ndx_hdr`5B9`5D; X char *desc, *bookfile, *defdir, *table, *sec_str, *tmp; X char bookpath`5B300`5D, ndx_name`5B256`5D; X unsigned char attr`5B4`5D; X bkrdr_recptr root; X bktxt_fntptr fontdef; X void *bkf, *bki; X /* X * setup CGI environment. X */ X status = cgi_init ( argc, argv ); X if ( (status`261) == 0 ) fprintf(stderr,"Status of cgi_init: %d`5Cn",`20 V\3C06 ); X if ( (status`261) == 0 ) exit ( \1806 ); X if ( argc < 2 ) `7B X`09error_abort ( "500 missing argument",`20 X`09`09"usage: webbook /path/file`5B.xnnn`5D.type`5B/`5D" ); X `7D X bookfile = file_arg; X i = strlen ( bookfile ); X if ( bookfile`5Bi-1`5D == '/' ) `7B X`09bookfile`5Bi-1`5D = '`5C0'; X`09return webbook_shelf ( bookfile,\1A09version ); X `7D else if ( (bookfile`5Bi-1`5D == '`5D') `7C`7C\1A14>') ) `7B X`09char *port; X`09/* X`09 * Idiot forgot the trailing slash, issure redirect. X */ X`09port = cgi_info("SERVER_PORT"); X`09if ( !port ) port = "80"; X`09if ( strcmp ( port, "80" ) == 0 ) port = ""; X`09cgi_printf("Location: http://%s%s%s%s%s/`5Cn`5Cn", cgi_info("SERVER_NAME"), V X`09`09*port ? ":" : "", port, cgi_info("SCRIPT_NAME"), bookfile ); X`09return 1; X `7D X /* X * Interpret command line arguments. X */ X i = strlen ( bookfile ); X if ( i+1 >= sizeof(bookpath) ) `7B X`09error_abort ( "400 bad argument", "A\0C07 too long" ); X `7D X strcpy ( bookpath, bookfile ); X /* X * Scan from back for filename portion and track the periods. X */ X select = type = dir_delim = i; X for (j=i-1; (j >= 0) `26`26 (bookpath`5Bj`5D != '/'); --j) `7B X`09if ( bookpath`5Bj`5D == '.' ) `7B X`09 if ( dir_delim != i ) ; X`09 else if ( type == i )\0C07 j; X`09 else if ( select == i )\0E09 j; X`09 else `7B X`09`09error_abort ( "404 bad filename", bookpath ); X`09 `7D X`09`7D`20 X`09else if ( (bookpath`5Bj`5D == '`5D') `7C`7C\1812>') ) `7B X`09 dir_delim = j; X`09`7D X `7D X href_fname = `26bookpath`5Bj+1`5D;`09/* just filename without path */ X X if ( select != i ) `7B X`09/* Reorder things, we stil have original in argv`5B1`5D */ X`09strcpy ( `26bookpath`5Bselect`5D, bookfile + type ); X`09strncpy ( `26bookpath`5Bselect-type+i`5D, bookfile+\1906, type - \2806 ); X`09bookpath`5Bselect-type+i`5D = '`5C0'; X`09j = i + select - type; X`09type = select; X`09select = j+1; X `7D Xfprintf(stdout,"argv`5B1`5D = '%s' ->\0806(%d)`5Cn", bookfile\0A06path, X`09strcspn (":`5B<", bookpath) ); X /* X * convert filename to vms format for bkf_open. X */ X if ( strcspn ( ":`5B<", bookpath ) > 3 ) `7B X vms_bookfile`5B0`5D = '`5C0'; X status = SHELL_TO_VMS ( bookpath, save_bookfile_name, 1 ); X if ( (status`261) == 0 ) `7B X`09 cgi_printf("Content-type: text/plain`5CnStatus: 404 bad filename`5Cn`5C Vn"); X`09 cgi_printf("Failure to convert filename format:'%s'`5Cn", vms_bookfile V ); X`09 exit(status); X `7D X `7D else `7B X`09/* Already in VMS format */ X`09strncpy ( vms_bookfile, bookpath`5B0`5D == '/' ? `26\16091`5D :\2409,`20 X`09`09255 ); X`09vms_bookfile`5B255`5D = '`5C0'; X `7D X i = strlen(vms_bookfile); X if ( i > 0 )\0D06vms_bookfile`5Bi-1`5D == '.' )`20 X`09strcpy ( `26vms_bookfile`5Bi`5D, "decw$book" ); Xfprintf(stdout,"VMS bookfile spec: '%s' (%d)`5Cn", vms_\2108, i ); X bookfile = vms_\0F08; X /* X * Make printf control strings for generating HREF targets for X * different tables. X */ X href_type = (bookpath`5Btype`5D == '.') ? `26\1A0D+1`5D :\140F`5D; X bookpath`5Btype`5D = '`5C0'; X href_fname = escape_string(\1B0A); /* encode punctuation */ X /* X * Select arguments X */ X defdir = "sys$disk:`5B`5D.decw$book"; X table = sec_str = (char *) 0; X if ( bookpath`5Bselect`5D == 'n' ) sec_str = `26\250F+1`5D; X else if ( bookpath`5Bselect`5D == 't' ) table = `26\230F+1`5D; X /* X * Open file, read root page, and display some of it's fields. X */ X status = bkf_open ( bookfile, defdir, `26bkf ); X if ( (status`261) == 0 ) `7B X`09cgi_printf("Content-type: text/plain`5Cn`5Cn"); X`09cgi_printf("error opening bookfile '%s'`5Cn",\120A);`20 X`09exit ( status ); X `7D X status = bkf_read_page ( bkf, 0, `26part_length, `26root, `26\1006 ); X if ( (status`261) == 0 ) `7B X`09cgi_printf("Content-type: text/plain`5Cn`5Cn"); X`09cgi_printf("error reading root part: %d`5Cn", status ); X`09exit ( status ); X `7D X if ( bookpath`5Bselect`5D != 'g' `26`26\1B16G' ) `7B X`09cgi_printf ( "Content-type: text/html`5Cn`5Cn" ); X cgi_printf("%s</\0A06</HEAD>`5Cn", entify(root->first.tit Vle)); X cgi_printf("<!-- partcount: %d, sectioncount %d -->`5Cn",`20 X `09root->first.partcount, \170Csectioncount ); X if ( root->first.author`5B0`5D ) cgi_printf("<!-- Author: %s.-->`5Cn" V, X`09 root->first.author ); X`09cgi_printf("<!-- Software: %s --><HEAD>`5Cn", webbook_version ); X `7D X /* X * Read font table. X */ X status = bkt_read_font_map ( bkf, `26fontde\0A08_count ); X /* X * Take action depending upon the first char of selector. X */ X part_num = 0; X switch ( bookpath`5Bselect`5D ) `7B X`09`09/* Convert section argument to part number and fall throuh */ X`09case 's': X`09case 'S': X`09`09single_sect = atoi ( `26bookpath`5Bselect+1`5D ); X`09 status = bkf_lookup_section ( bkf, single_sect, `26part_num ); X`09`09 X`09case 'p': X`09case 'P': X`09`09if ( part_num == 0 )\100B atoi ( `26bookpath`5Bselect+1`5D ); X`09`09status = show_part ( bkf, part_num, fontdef, font_count ); X X`09 break; X`09case '`5C0': X`09case 't': X`09case 'T': X`09 /* X`09 * Create context for index operations. X`09 */ X`09 status = bki_create_context ( bkf, `26bki ); X`09 if ( (status`261) == 0 ) `7B X`09`09cgi_printf("error creating index context`5Cn" );`20 X`09`09exit ( status ); X`09 `7D X`09 /* X`09 * Make directory of indexes. X`09 */ X`09 table = bookpath`5Bselect`5D ? `26\140F+1`5D : ""; X`09 cgi_printf ( "<H2>Available tables:</H2><UL>`5Cn" ); X X`09 for ( status = bki_find_index ( bki,"*",-1, ndx_name, X`09`09 `26ndx_type,\0B06count ); (status`261) == 1; X`09 `09 status = bki_find_index ( bki, "*", -1, ndx_name, X`09 `09`09`26ndx_type, `26ndx_count ) ) `7B X`09 cgi_printf("<LI><A HREF=`5C"%s.t%s.%s`5C">%s</A> (%d entries)</ VLI><BR>`5Cn", X`09 \0808href_fname, ndx_\0A06href_type,`20 X`09`09`09ndx_name, ndx_count ); X`09 `7D X`09 bki_find_index_end ( bki ); X`09 cgi_printf("</UL>`5Cn"); X`09 if (strcmp(table,"*") == 0) break; X`09 /* X`09 * List named table. X`09 */ X`09 if ( *table == '`5C0' ) `7B X`09`09/* Lookup first table */ X`09`09status = bki_find_index ( bki, "*", 5, ndx_name, `26ndx_type, X`09`09`09`26ndx_count ); Xfprintf(stderr, "Find status for default index: %d, name: %s`5Cn",`20 Xstatus, ndx_name ); X`09`09table = ndx_name; X`09 `7D X X`09 status = bki_open_index ( bki, table ); X`09`09if ( (status`261) == 0 ) `7B X`09`09 cgi_printf("Unable to open index '%s'`5Cn", ndx_name ); X`09`09 break; X`09`09`7D X`09 cgi_printf("<HR><H2>%s</H2>(%d entries)<UL>`5Cn", entify(table),`20 X`09`09`09ndx_count ); X`09 for ( ; ; ) `7B X`09`09int first; X`09`09status = bki_read_index( bki, ndx_hdr, attr, ndx_name,`20 X`09`09`09`26desc, `26ndx_value); X X`09`09if ( (status`261) == 0 ) break; X`09`09if ( ndx_value <= 0 `7C`7C\120B> root->first.sectioncount) `7B X`09`09 cgi_printf("</UL>%s<UL>`5Cn", entify(desc) ); X`09 `09`7D else `7B X`09 status = bkf_lookup_first_section`20 X`09`09`09( bkf, ndx_value, `26part_num, `26first ); X`09`09 cgi_printf("<LI><A HREF=`5C"%s.p%d.%s#%d`5C">%s</A></LI><BR>`5Cn",`20 V X`09`09`09href_fname, part_num, href_type, ndx_value,`20 X`09`09`09entify(desc) ); X`09`09`7D X`09 `7D X`09 cgi_printf("</UL>`5Cn"); X X`09break; X`09case 'g': X`09case 'G': X`09 /* X`09 * Return figure as graphic image, argument is section number. X`09 */ X`09 `09cgi_printf ( "Content-type: image/gif`5Cn`5Cn" ); X`09`09single_sect = atoi ( `26bookpath`5Bselect+1`5D ); X`09 status = bkf_lookup_section ( bkf, single_sect, `26part_num ); X`09`09if ( (status`261) == 1 )`09\1106 = show_image(bkf, single_sect); X`09`09else `7B X`09`09`7D X`09default: X`09break; X `7D X if ( bookpath`5Bselect`5D != 'g' `26`26\1B16G' ) X`09cgi_printf("</BODY>`5Cn"); X X /* X * Cleanup. X */ X status = bkf_close ( bkf ); X return status; X`7D X/* Sub-record summary information */ Xstruct sb_summary `7B X`09int type; X`09int length; X`09struct sb_summary *hot;`09`09/* link to hotspot def */ X`09long hdr`5B9`5D; X`7D; X Xstruct convert_ctx `7B X /* input state (bookreader) */ X void *bkf, *cursor; X bktxt_fntptr fontdef; X int font_count, cur_font; X int in_x, in_y; X X /* output state (HTML) */ X int bold_on; X int italic_on; X int monospace_on; X int font_nonprintable; X int hdr_level; X int dl_depth;`09`09/* indentation level ((x-100)/50)) */ X int out_x, out_y;`09`09/* virtual */ X`7D; X X Xstatic struct sb_summary *check_hotspot`20 X`09( short x,\0907y, struct sb_summary *hot ) X`7B X for ( ; hot; hot = hot->hot ) `7B X`09/* cgi_printf("`5Cncheckhot x: %d y: %d, spot: %d %d lw\0A07`5Cn", x, y, X`09 hot->hdr`5B3`5D,\0C094\0C0B5\180B6`5D); */ X`09if ( hot->hdr`5B4`5D <= y `26`26\140C+\20096`5D >\2006 X`09 hot->hdr`5B3`5D <= x `26`26\140D+\220A5`5D >= x ) return hot; X `7D X return hot; X`7D X/* X * Generate necessary HTML to change from current font to desired\1006and X * update state. X */ Xstatic int change_font ( unsigned char new_font, struct convert_ctx *cvt ) X`7B X bktxt_fntptr fnt; X if ( new_font < 0 `7C`7C\100A>= cvt->font_count ) return 0; X X cvt->cur_font = new_font; X fnt = `26cvt->fontdef`5Bnew_font`5D; X if ( cvt->bold_on ) `7B X`09if ( fnt->weight`5B0`5D != 'B' ) `7B cvt->bold_on = 0; cgi_printf("</B>"); V `7D X `7D else `7B X`09if ( fnt->weight`5B0`5D == 'B' ) `7B cvt->bold_on = 1; cgi_printf("<B>");`20 V`7D X `7D X X if ( cvt->italic_on ) `7B X`09if ( fnt->style`5B0`5D != 'I' ) `7B cvt->italic_on = 0; cgi_printf("</I>"); V `7D X `7D else `7B X`09if ( fnt->style`5B0`5D == 'I' ) `7B cvt->italic_on = 1; cgi_printf("<I>"); V `7D X `7D X if ( cvt->monospace_on ) `7B X`09if ( fnt->spacing`5B0`5D != 'P' ) `7B cvt->monospace_on = 1; cgi_printf("<T VT>"); `7D X `7D else `7B X`09/* test for proportional spacing */ X`09if ( fnt->style`5B0`5D == 'P' ) `7B cvt->monospace_on = 0; cgi_printf("</TT V>"); `7D X `7D X if ( cvt->font_nonprintable ) `7B X`09if ( fnt->encoding`5B0`5D != '*' ) cvt->font_nonprintable = 0; X `7D else `7B X`09if ( fnt->encoding`5B0`5D == '*' ) cvt->font_nonprintable = 1; X `7D X return 1; X`7D X X/* X * Generate HTML to perform line breaks. X */ X#ifdef OLD_WAY Xstatic void change_line ( int new_x,\0B09y, struct convert_ctx *cvt ) X`7B X int target_dl; X X target_dl = (new_x-100) / 50; X if ( target_dl > cvt->dl_depth ) `7B X`09/* Change indentation level */ X`09while ( target_dl > cvt->dl_depth ) `7B X`09 cgi_printf("<DL><DD>"); X`09 cvt->dl_depth++; X`09`7D X `7D else if ( target_dl < cvt->dl_depth ) `7B X`09while ( target_dl < cvt->dl_depth ) `7B X`09 cgi_printf("</DD></DL>"); X`09 cvt->dl_depth--; X`09`7D X`09cgi_printf("`5Cn"); X `7D else `7B X X cgi_printf( (new_y - cvt->in_y) > 100 ? "<P>`5Cn" : "<BR>`5Cn"); X `7D X cvt->in_x =\0C06dl_depth * 50; X`7D X#endif Xstatic void change_line ( int new_x,\0B09y, struct convert_ctx *cvt\2406para ) V X`7B X int target_dl, i; X char indent`5B200`5D; X X target_dl = ((new_x) / 50) * 2; X if ( target_dl > 120 )\120B= 60; X if ( target_dl < 0 )\100B= 0; X for ( i = 0; i < target_dl; i++ ) indent`5Bi`5D = nbsp; X indent`5Btarget_dl`5D = '`5C0'; X cgi_printf ( "%s`5Cn%s", para ? "<p>" : "<br>", indent ); X`7D X Xstatic int format_bodytext ( struct convert_ctx *cvt,\1908sb_summary *sb ) X`7B X int status, is_last, t_len, t_type, i, offset, glue, slen, is_link; X short h_v`5B2`5D; unsigned char attr`5B4`5D; char *data\0C07buffer`5B256 V`5D; X /* X * Scan sub-sections. X */ X cgi_printf ( "<A NAME=`5C"%d`5C">", sb->hdr`5B1`5D ); X for ( is_last = 0; !\0E07; ) `7B X`09status = bks_read_section`20 X`09`09( cvt->cursor, `26t_type, h_v, att\1406len, `26data, `26is_last ); X`09if ( (status`261) == 0 )`20 X`09`09 cgi_printf("%sread error, status: %d, is_last: %d%s`5Cn", X`09`09`09is_last ? "<!-- ":"", status, \1E07,`20 X`09`09`09is_last ? " -->" :"" ); X`09if ( (status`261) == 0 ) break; X#ifdef VERBOSE X`09cgi_printf("<!-- subtxt: t=%d h=%d v=%d attr: %d %d \0606-->`5Cn", X`09 t_type, h_v`5B0`5D\08061`5D, attr`5B0`5D, attr`5B\12092\1B083`5D ); X#endif X X`09if ( t_type == 3 `7C`7C\0F0B2 ) `7B X`09 struct sb_summary *hot_link; X X`09 if ( attr`5B0`5D != cvt->cur_font ) change\0E06\2909, cvt ); X`09 if ( cvt->in_y > h_v`5B1`5D ) `7B X`09`09change_line ( h_v`5B0`5D, h_v`5B1`5D, cvt, 1 ); X`09 `7D else if ( (cvt->in_x > h_v`5B0`5D) `7C`7C\180Ay < h_v`5B1`5D) ) `7B V X`09`09change_line ( h_v`5B0`5D, h_v`5B1`5D, cvt, 0 ); X`09 `7D else cgi_printf ( " " ); /* separate words */ X X`09 hot_link = sb->hot; X`09 if (hot_link) \0A08 = check_hotspot ( h_v`5B0`5D, h_v`5B1`5D, sb->hot ) V; X`09 if ( hot_link ) `7B X`09`09if ( hot_link->hdr`5B7`5D == sb\0E061`5D ) X`09`09 cgi_printf ( "<A HREF=`5C"#7%d`5C">", hot_link->hdr`5B7`5D ); X`09`09else `7B X`09`09 int part_num; X`09`09 bkf_lookup_section ( cvt->bkf,`20 X`09`09`09hot_link->hdr`5B7`5D, `26part_num ); X`09`09 cgi_printf ( "<A HREF=`5C"%s.p%d.%s#%d`5C">", href_fname, X`09`09`09part_num, href_type, hot_link->hdr`5B7`5D ); X`09`09`7D X`09 `7D X X`09 cvt->in_x = h_v`5B0`5D;\1409y\14071`5D; X`09 for ( offset = 0;\0C08< t_len; ) `7B X`09`09bkt_text3_scan ( t_len, data, `26offset, buffer, `26slen, `26glue ); X`09`09if ( offset < t_len ) buffer`5Bslen++`5D = ' '; X`09`09buffer`5Bslen`5D = '`5C0'; X`09`09if ( cvt->font_nonprintable ) `7B char jj; X`09`09 for ( jj = 0; jj < slen; jj++ ) buffer`5Bjj`5D = '.'; X`09`09 cvt->in_x = 1000; X`09`09`7D X`09`09cgi_printf("%s", entify(buffer)); X#ifdef VERBOSE X`09`09cgi_printf("<g%x>", glue); X#endif X`09 `7D X X`09 if ( hot_link ) cgi_printf ( "</A>" ); X`09`7Delse if ( t_type == 1 ) `7B X`09 cgi_printf("<HR> <!-- type 1 subrec -->`5Cn"); X`09 cvt->in_x = 0;\0F09y += 40; X`09`7D X `7D X cgi_printf("</A><BR>`5Cn"); X cvt->in_x = 0; X return status; X`7D X X Xstatic int show_part ( void * bkf, int part_num, bktxt_fntptr fontdef,`20 X`09int font_count ) X`7B X struct convert_ctx cvt; X char *desc; X long ndx_value, hdr`5B9`5D; X int j, i, part_info`5B4`5D, sec\0E09; X int status, count, match, iter\0606_\1907type, length, is_last; X short ndx_hdr`5B9`5D; X char name`5B256`5D; X struct sb_summary *sb; X /* X * Create data structures used by bookfile_section.c X */ X cvt.bkf = bkf; X cvt.fontdef = \0A07; X cvt.font_count = \0D0A; X cvt.hdr_level = 0; X cvt.dl_depth = 0; X status = bks_create_section_cursor ( bkf, `26cvt.\1307); X if ( (status`261) == 0 ) `7B X cgi_printf("Error creating cursor: %d`5Cn", status ); X`09exit ( status ); X `7D X /* X * Position to begining of part, seek function returns number of X * sub-records (sections) in part. X */ X status = bks_seek_part ( cvt.cursor, part_num, 0, `26iter_count ); X if ( (status`261) == 0 ) `7B X cgi_printf("Error seeking part: %d`5Cn", status ); X`09exit ( status ); X `7D X /* X * Make links to previous and next. X */ X status = bks_get_cursor_info ( cvt.\1206, part_info, sec\0B06 ); X if ( (status`261) == 1 ) `7B X`09if ( part_info`5B2`5D > 0 )`09cgi_printf("`5B<A HREF=`5C"%s.p%d.%s`5C">next V</A>`5D ",`20 X`09`09href_fname, part_info`5B2`5D, href_type ); X`09else cgi_printf ( "`5Bnext`5D " ); X`09if ( part_info`5B1`5D > 0 ) cgi_printf("`5B<A HREF=`5C"%s.p%d.%s`5C">previo Vus</A>`5D ",`20 X`09`09href_fname, part_info`5B1`5D, href_type ); X`09else cgi_printf ( "`5Bprevious`5D " ); X`09cgi_printf("`5B<A HREF=`5C"%s.%s`5C">contents</A>`5D<BR><HR>`5Cn", href_fna Vme, X`09`09href_type ); X `7D X /* X * Allocate array to hold summary information. X */ X sb = (struct sb_summary *) malloc(iter_count*sizeof\2E12)); X if ( !sb ) return 0; X for ( iter = 0;\0A06< iter_count\1306++ )`20 X`09`09sb`5Biter`5D.hot = (struct sb_summary *) 0; X /* X * Make first pass over part to get header info and hotspot info. X */ X for ( iter = 0;\0A06< iter_count\1306++ ) `7B X`09status = bks_seek_section ( cvt.cursor, iter? 1 : 0, 1, `26sb`5Biter`5D.typ Ve,`20 X`09`09`26sb`5Biter`5D.length, \1109hdr ); X`09if ( (status`261) == 0 ) cgi_printf("Error in seek: %d`5Cn", status); X`09if ( (status`261) == 0 ) break; X`09if ( sb`5Biter`5D.type == BKSBREC_FIGHOT ) `7B X`09 i = sb`5Biter`5D.hdr`5B2`5D; X`09 for ( j = iter-1; j >=0; --j ) if ( sb`5Bj`5D.type == BKSBREC_BODYTEXT V X`09`09`09`26`26 (sb`5Bj`5D.hdr`5B1`5D == i) ) `7B X`09 sb`5Biter`5D.hot = sb`5Bj`5D.hot; X`09 sb`5Bj`5D.hot = `26sb`5Biter`5D; X`09 `7D X`09`7D X `7D X /* X * Make second pass over data to output it. X */ X cvt.cur_font = -1; X cvt.in_x = 0; X cvt.in_y = 10000; X cvt.bold_on = cvt.italic\100Amonospace\23060; X cvt.font_nonprintable = 0; X status = bks_seek_part ( cvt.cursor, part_num, 0, `26iter_count ); X if ( (status`261) == 0 ) `7B X cgi_printf("Error seeking part: %d`5Cn", status ); X`09exit ( status ); X `7D X for ( iter = 0;\0A06< iter_count\1306++ ) `7B X`09status = bks_seek_section ( cvt.cursor, iter? 1 : 0, 1, `26type,`20 X`09`09`26length, hdr ); X`09if ( (status`261) == 0 ) break; X`09/* cgi_printf("section type: %d, length: %d nxthost: %d`5Cn",`20 X`09`09type, length, sb`5Biter`5D.hot ); */ X X`09if ( type == BKSBREC_BODYTEXT ) `7B X#ifdef VERBOSE X`09 int k;`20 X`09 static char *hnm`5B9`5D = `7B "`5B0`5D", "sec", "`5B2`5D", "`5B3\07064 V`5D", X`09`09`09"`5B5`5D", "hgt", "`5B7`5D", "`5B8`5D" `7D; X`09 cgi_printf("`5Cn<!-- bodytext hdr:" ); X`09 for ( k = 0; k < 9; k++ ) if ( hdr`5Bk`5D ) cgi_printf ( " %s=%d", X`09`09`09hnm`5Bk`5D, hdr`5Bk`5D ); X`09 cgi_printf("-->`5Cn"); X#endif X`09 status = format_bodytext ( `26cvt, `26sb`5Biter`5D ); X`09`7D else if ( type == BKSBREC_FIGURE ) `7B X`09 int t_len, t_type, is_last; X`09 short h_v`5B2`5D; unsigned char attr`5B4`5D; char *data\0C07buffer`5B25 V6`5D; X`09 cgi_printf( X`09`09"<!-- figure sec %d pos: (%d,%d) size: (%d %d)=%d type: %d -->`5Cn", X`09`09hdr`5B2`5D, hdr`5B3\08074\10075\18076`5D, length\28067`5D`26255 ); X`09 /* */ X`09 status = bks_read_section`20 X`09`09( cvt.cursor, `26t_type, h_v, att\1406len, `26data, `26is_last ); X X`09 cgi_printf("<IMG SRC=`5C"%s.g%d.%s`5C">",`20 X`09`09href_fname, hdr`5B2`5D, href_type ); X`09`7D X `7D X if ( cvt.monospace_on ) cgi_printf("</TT>"); X if ( cvt.italic_on ) cgi_printf("</I>"); X if ( cvt.bold_on ) cgi_printf("</B>"); X bks_delete_section_cursor ( cvt.\0D07); X return status;`20 X`7D X Xstatic int out_to_netlink ( void *fptr, int size, char *buffer ) X`7B X int status; X#ifndef NOCGILIB X status = net_link_write ( buffer, size ); X return status; X#else X status = fwrite ( buffer, size, 1, (FILE *) fptr ); X return 1; X#endif X`7D Xstatic int show_image ( void *bkf,\1C06ect_num ) X`7B X void *cursor; X long hdr`5B9`5D; X int j, i, k, width, height, mask, value, t_type, t_len; X int status, count, match, type, length, is_last; X short *cols, *rows; X short h_v`5B2`5D; unsigned char attr`5B4`5D; X char *data; X unsigned char *cur_row,\0A06col; X unsigned char *pixel_image,\0E08row; X unsigned char color_table`5B6`5D = `7B 0, 0, 0, 255, 255, 255 `7D; X /* X * Seek to section containing image. X */ X status = bks_create_section_cursor ( bkf, `26\0F07); X if ( (status`261) == 1 ) \1106 = bks_seek_section`20 X`09( cursor, sect_num, 0, `26type, `26length, hdr ); X while ( (type != BKSBREC_FIGURE) `26`26 ((status`261) == 1) ) `7B X`09status = bks_seek_section ( cursor, 1, 1, `26type, `26length, hdr ); X `7D X if ( (status`261) == 1 ) \1106 = bks_read_section`20 X`09`09( cursor, `26t_type, h_v, att\1406len, `26data, `26is_last ); X if ( (status`261) == 0 ) `7B X cgi_printf("Error retrieving figure data: %d`5Cn", status ); X`09exit ( status ); X `7D X if ( type == BKSBREC_FIGURE ) `7B X`09/* X`09 * Create gif file, with data going back to net link. X`09 */ X#ifdef NOCGILIB X`09char fname`5B256`5D; X`09FILE *out; X`09sprintf ( fname, "%s-g%d.gif", href_\1A07sect_num ); X`09out = fopen ( fname, "wb" ); X`09if ( !out ) `7B`20 X`09 fprintf(stderr, "Error openning '%s'`5Cn", fname ); X`09`7D else `7B X#else X`09 void *out; X`09 out = (void *) 0; X#endif X`09 status = bkg_convert_figure_to_gif`20 X`09`09( hdr, (unsigned char *) data, t_len, out_to_netlink, out ); X#ifdef NOCGILIB X`09 fprintf(stderr,"status of gif generate (%s): %d`5Cn", fname, \2B07); X`09 fclose ( out ); X`09`7D X#endif X `7D X /* X * Cleanup up. X */ X bks_delete_section_cursor ( \0907); X return status; X`7D +-+-+-+-+-+-+-+- END OF PART 4 +-+-+-+-+-+-+-+- ================== RFC 822 Headers ================== Return-Path: VMSSERV@kcl.ac.uk Received: by galaxy.zko.dec.com (UCX V4.0-10B, OpenVMS V6.2 VAX); Mon, 19 Aug 1996 18:17:09 -0400 Received: from newt.kcl.ac.uk by mail11.digital.com (8.7.5/UNX 1.2/1.0/WV) id SAA13081; Mon, 19 Aug 1996 18:03:21 -0400 (EDT) Received: from alder.cc.kcl.ac.uk by newt.kcl.ac.uk with SMTP (PP) id <23300-0@newt.kcl.ac.uk>; Mon, 19 Aug 1996 23:03:00 +0100 Received: by alder.cc.kcl.ac.uk (MX V4.2 AXP) id 731; Mon, 19 Aug 1996 23:03:21 EDT Date: Mon, 19 Aug 1996 23:03:07 BST From: Kings College London File Server <VMSSERV@kcl.ac.uk> To: everhart@star.zko.dec.com Message-ID: <009A71AB.0C253DC0.731@alder.cc.kcl.ac.uk> Subject: WEBBOOK.4-OF-5