Go to Google Groups Home *Groups* Advanced Groups Search Preferences Groups Help *Groups search result 1* for *txt2pdf.c group:comp.os.vms* Search Result 1 From: Craig A. Berry (craig.berry@nospam.SignalTreeSolutions.com ) Subject: Re: Text or FTN -> PDF - *txt2pdf*.*c* (1/1) This is the only article in this thread View: Original Format Newsgroups: comp.os.vms Date: 2001-09-30 13:19:16 PST In article , chris_doran@my-deja.com (Chris Doran) wrote: > "Dave Pampreen" wrote in message > news: ... > > Is there a converter(s) that will take a text file (Fortran carriage > > control) file and convert it to PDF? > > *TXT2PDF*: http://www.planetpdf.com/mainpage.asp?WebPageID=156 > > This gives what I suspect is an early PDF file format which is > acceptable to the real Acrobat reader, but not to some others. It > works on VMS (use DEFINE/USER to redirect stdin/stdout to files). I > assume that compiled/linked with DEC *C* it will handle FORTRAN CC, but > I haven't tried it. I've been using this one, but ran into a few problems that caused me to add the enhancements included in the version attached here. The results I've been getting with my version have been readable with XPDF on VMS, various versions of Acrobat Reader on Mac and Windows, and the Preview application that comes with Mac OS X. These are my changes: 1.) ftell() was not working on pipes, so I added a simple counter so *txt2pdf* always knows how many chars it has written. 2.) Windows versions of Acrobat Reader yelp (though can usually still read the file) if the lines end with CRLF rather than just CR, so I changed \n to \r throughout. In my (limited) tests I have not seen this cause problems on other platforms. 3.) I added some code to do input and output redirection so you can just say MCR []*TXT2PDF* < FOO.TXT > FOO.PDF without having to use pipes or reassignments. N.B. If you do use one of the latter methods, your output files will be VFC, variable-length. If you then ftp such a file in ASCII mode, things will seem fine until you get a file larger than 32K, at which point you'll get unexpected line breaks at 32K intervals (the maximum record length for VFC). So, ftp it in binary mode or use the redirection I've built in, which reopens the output file as Stream_CR with carriage return carriage control. /* Copyright 1998 P. G. Womack, Diss, Norfolk, UK. "BugBear" Do what you like, but don't claim you wrote it. 2001, VMS mods by Craig Berry (not claiming I wrote it) */ #include #include #include #include float page_width = 594.0; float page_depth = 828.0; float margin = 30.0; float font_size = 10.0; float lead_size = 10.0; int object_id = 1; int page_tree_id; long int chars_out = 0; typedef struct _PageList { struct _PageList *next; int page_id; } PageList; int my_printf(const char *format_string, ... ) { char tmpbuf[1024]; va_list args; va_start(args, format_string); chars_out += vsprintf(tmpbuf, format_string, args); va_end(args); return fputs(tmpbuf, stdout); } int num_pages = 0; PageList *pages = NULL; PageList **insert_page = &pages; store_page(int id) { PageList *n = (PageList *)malloc(sizeof(*n)); if(n == NULL) { fprintf(stderr, "Unable to allocate array for page %d.", num_pages + 1); exit(1); } n->next = NULL; n->page_id = id; *insert_page = n; insert_page = &n->next; num_pages++; } int num_xrefs = 0; long *xrefs = NULL; start_object(int id) { if(id >= num_xrefs) { long *new_xrefs; int delta, new_num_xrefs; delta = num_xrefs / 5; if(delta < 1000) delta += 1000; new_num_xrefs = num_xrefs + delta; new_xrefs = (long *)malloc(new_num_xrefs * sizeof(*new_xrefs)); if(new_xrefs == NULL) { fprintf(stderr, "Unable to allocate array for object %d.", id); exit(1); } memcpy(new_xrefs, xrefs, num_xrefs * sizeof(*xrefs)); free(xrefs); xrefs = new_xrefs; num_xrefs = new_num_xrefs; } xrefs[id] = chars_out; my_printf("%d 0 obj\r", id); } int stream_id, stream_len_id; long stream_start; float ypos; start_page() { stream_id = object_id++; stream_len_id = object_id++; start_object(stream_id); my_printf("<< /Length %d 0 R >>\r", stream_len_id); my_printf("stream\r"); stream_start = chars_out; my_printf("BT\r/F0 %g Tf\r", font_size); ypos = page_depth - margin; my_printf("%g %g Td\r", margin, ypos); my_printf("%g TL\r", lead_size); } end_page() { long stream_len; int page_id = object_id++; store_page(page_id); my_printf("ET\r"); stream_len = chars_out - stream_start; my_printf("endstream\rendobj\r"); start_object(stream_len_id); my_printf("%ld\rendobj\r", stream_len); start_object(page_id); my_printf("<>\rendobj\r", page_tree_id, stream_id); } do_text() { char buffer[8192]; start_page(); while(gets(buffer) != NULL) { if(ypos < margin) { end_page(); start_page(); } if(strlen(buffer) == 0) my_printf("T*\r"); else { if(buffer[0] == '\f') { end_page(); start_page(); } else { char *c*, *s = buffer; putchar('('); chars_out++; while((*c* = *s++) != '\0') { switch(*c*) { case '(': case ')': case '\\': putchar('\\'); chars_out++; } putchar(*c*); chars_out++; } my_printf(")'\r"); } } ypos -= lead_size; } end_page(); } #ifdef __VMS #include void initialize_main ( int *argc, char **argv[] ) { int i, j, k, new_argc = 0; int append; char **vms_argv; FILE *f; vms_argv = (char **) malloc((*argc+1) * sizeof(char*)); vms_argv[new_argc++] = **argv; for (i = 1; i < *argc; i++) { if (argv[0][i][0] == '>') { k = 1; append = 0; if (argv[0][i][k] == '>') { k++; append++; } if (argv[0][i][k]) { f = freopen(argv[0][i]+k,append?"a":"w",stdout,"rat=cr","rfm=stmcr"); if (!f) { perror("stdout redirection"); exit(SS$_ABORT); } } else if (i+1 < *argc && argv[0][i+1] && *argv[0][i+1]) { f = freopen(argv[0][i+1],append?"a":"w",stdout,"rat=cr","rfm=stmcr"); if (!f) { perror("stdout redirection"); exit(SS$_ABORT); } i++; } } else if (argv[0][i][0] == '2' && argv[0][i][1] == '>') { k = 2; append = 0; if (argv[0][i][k] == '>') { k++; append++; } if (argv[0][i][k]) { if (argv[0][i][k] == '&') { if (argv[0][i][k+1] != '1') exit(SS$_BADPARAM); stderr = stdout; } else { f = freopen(argv[0][i]+k,append?"a":"w",stderr); if (!f) { perror("stderr redirection"); exit(SS$_ABORT); } } } else if (i+1 < *argc && argv[0][i+1] && *argv[0][i+1]) { if (argv[0][i+1][0] == '&') { if (argv[0][i+1][1] != '1') exit(SS$_BADPARAM); stderr = stdout; } else { f = freopen(argv[0][i+1],append?"a":"w",stderr); if (!f) { perror("stderr redirection"); exit(SS$_ABORT); } } i++; } } else if (*argv[0][i] == '<') { if (argv[0][i][1]) { f = freopen(argv[0][i]+1,"r",stdin); if (!f) { perror("stdin redirection"); exit(SS$_ABORT); } } else if (i+1 < *argc && argv[0][i+1] && *argv[0][i+1]) { f = freopen(argv[0][i+1],"r",stdin); if (!f) { perror("stdin redirection"); exit(SS$_ABORT); } i++; } } else { vms_argv[new_argc++] = argv[0][i]; } } *argc = new_argc; vms_argv[new_argc] = NULL; *argv = vms_argv; } #endif /* __VMS */ int main(int argc, char **argv) { int i, catalog_id, font_id; long start_xref; #ifdef __VMS /* handle Unix-style command-line redirection */ initialize_main(&argc, &argv); #endif my_printf("%%PDF-1.0\r"); page_tree_id = object_id++; do_text(); font_id = object_id++; start_object(font_id); my_printf("<>\rendobj\r"); start_object(page_tree_id); my_printf("<page_id); ptr = ptr->next; } my_printf("]\r"); } my_printf("/Resources<> >>\r", font_id); my_printf("/MediaBox [ 0 0 %g %g ]\r", page_width, page_depth); my_printf(">>\rendobj\r"); catalog_id = object_id++; start_object(catalog_id); my_printf("<>\rendobj\r", page_tree_id); start_xref = chars_out; my_printf("xref\r"); my_printf("0 %d\r", object_id); my_printf("0000000000 65535 f \r"); for(i = 1; i < object_id; i++) my_printf("%010ld 00000 n \r", xrefs[i]); my_printf("trailer\r<<\r/Size %d\r/Root %d 0 R\r>>\r", object_id, catalog_id); my_printf("startxref\r%ld\r%%%%EOF\r", start_xref); exit(0); return 0; } ------------------------------------------------------------------------ Google Home - Advertise with Us - Search Solutions - Services & Tools - Jobs, Press, & Help ©2002 Google