IDENTIFICATION DIVISION. PROGRAM-ID. Enpage. * * DATE-WRITTEN. April 5, 1985. * AUTHOR. Ken Richardson. * * Written to the glory of God - 1 Corinthians 10:31 * * This program adds page breaks, top margins, and left margins * to an input text file (ci$input), creating a new file (ci$output). * Optionally, the second and subsequent pages can go to ci$output_2. * * Eleven control parameters can be supplied on the command line, * separated by spaces: * * left margin (must be >= 0) * top margin (must be >= 0) * maximum printable lines per page (must be > 0) * statistics desired (must be T for true or F for false) * * secondary output desired (must be T for true or F for false) * vertical pitch (must be >= 0, where 0 = font default) * horizontal pitch (must be >= 0, where 0 = font default) * * page format (must be 0, P for portrait, or L for landscape, where 0 = no change) * type family (must be 0, DBULTN1, RCOURIR, or RELITE0, where 0 = no change) * type size (must be 0, 6.7 or 10, where 0 = font default) * * tab size (must be > 0) * * Defaults: 10 6 55 T F 0 0 0 0 0 8 * ENVIRONMENT DIVISION. CONFIGURATION SECTION. SPECIAL-NAMES. SYMBOLIC ascii-backspace is 09 ascii-tab is 10 ascii-formfeed is 13 ascii-escape is 28 . SOURCE-COMPUTER. VAX-11. OBJECT-COMPUTER. VAX-11. INPUT-OUTPUT SECTION. FILE-CONTROL. select input-file assign to "ci$input:" organization is sequential . select output-file-1 assign to "ci$output:" organization is sequential . select output-file-2 assign to "ci$output_2:" organization is sequential . I-O-CONTROL. same record area for output-file-1 output-file-2 . DATA DIVISION. FILE SECTION. FD input-file record varying depending on input-record-length . 01 input-record. 02 filler pic x(1024). FD output-file-1 record varying depending on output-record-length . 01 output-record-1. 02 filler pic x(1024). FD output-file-2 record varying depending on output-record-length . 01 output-record-2. 02 filler pic x(1024). WORKING-STORAGE SECTION. 01 constants. 02 backspace-char pic x value ascii-backspace. 02 decipoints-per-inch pic s9(9) comp value 720. 02 declff-erase-fonts-record-size pic s9(9) comp value 10. 02 escape-char pic x value ascii-escape. 02 formfeed-char pic x value ascii-formfeed. 02 gss-record-size pic s9(9) comp value 7. 02 hpa-record-size pic s9(9) comp value 4. 02 ignore-blanks-and-tabs pic s9(9) comp value 17. 02 longword-size-in-bytes pic s9(9) comp value 4. 02 page-format-constants. 03 page-format-unchanged-k pic x value "0". 03 page-format-portrait-k pic x value "P". 03 page-format-landscape-k pic x value "L". 02 pfs-landscape-record-size pic s9(9) comp value 7. 02 pfs-portrait-record-size pic s9(9) comp value 7. 02 ris-record-size pic s9(9) comp value 2. 02 scanc-mask pic x value "X". 02 sgr-record-size pic s9(9) comp value 5. 02 spi-record-size pic s9(9) comp value 11. 02 tab-char pic x value ascii-tab. 02 type-family-constants. 03 type-family-unchanged-k pic x(7) value "0". 03 type-family-dbultn1-k pic x(7) value "DBULTN1". 03 type-family-rcourir-k pic x(7) value "RCOURIR". 03 type-family-relite0-k pic x(7) value "RELITE0". 02 vpa-record-size pic s9(9) comp value 4. 02 ws-false pic x value "F". 02 ws-true pic x value "T". 01 constant-tables. 02 horizontal-formatting-chars. * ------ control characters ------ * @abcdefghijklmnopqrstuvwxyz----- !"#$%&'()*+,-./0123456789:;<=>? 03 filler pic x(64) value " XX X ". * @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ 03 filler pic x(64) value " ". * ???????????????????????????????????????????????????????????????? 03 filler pic x(64) value " ". * ???????????????????????????????????????????????????????????????? 03 filler pic x(64) value " ". 01 variables. 02 control-parameters. 03 horizontal-pitch pic s9(4)v9(5) comp value zero. 03 left-margin pic s9(9) comp value 10. 03 maximum-lines-per-page pic s9(9) comp value 55. 03 page-format-flag pic x value "0". 03 tab-size pic s9(9) comp value 8. 03 top-margin pic s9(9) comp value 6. 03 top-margin-minus-one pic s9(9) comp value zero. 03 type-family pic x(7) value "0". 03 type-size pic s9(4)v9(5) comp value zero. 03 vertical-pitch pic s9(4)v9(5) comp value zero. 02 current-output-file pic s9(9) comp value zero. 02 d-floating-hold-variable comp-2. 02 display-count pic z,zzz,zz9. 02 extra-precision-bits pic x. 02 fill-spaces-required pic s9(9) comp. 02 hold-current-output-file pic s9(9) comp. 02 horiz-formatting-char-offset pic s9(9) comp. 02 input-parameter-text-variables. 03 input-param-aux-file-requested pic x(20). 03 input-param-horizontal-pitch pic x(20). 03 input-param-left-margin pic x(20). 03 input-param-max-lines pic x(20). 03 input-param-page-format pic x(20). 03 input-param-stats-requested pic x(20). 03 input-param-tab-size pic x(20). 03 input-param-top-margin pic x(20). 03 input-param-type-family pic x(20). 03 input-param-type-size pic x(20). 03 input-param-vertical-pitch pic x(20). 03 input-parameters pic x(80). 02 input-parameters-length pic s9(9) comp. 02 input-record-length pic 9(9) comp. 02 next-input-char pic s9(9) comp. 02 next-output-char pic s9(9) comp. 02 next-text-line-on-page pic s9(9) comp. 02 normal-char-count pic s9(9) comp. 02 output-line-count pic s9(9) comp value zero. 02 output-page-count pic s9(9) comp value zero. 02 output-record-length pic 9(9) comp. 02 remaining-input-chars pic s9(9) comp. 02 signed-longword-hold-variable pic s9(9) comp. 02 tab-offset pic s9(9) comp. 02 tmp-next-char pic s9(9) comp. 02 tmp-prior-char pic s9(9) comp. 02 unknown-horizontal-char-count pic s9(9) comp value zero. 01 declff-erase-fonts-record. 02 filler pic x value ascii-escape. 02 filler pic x(7) value "P0;1;0y". 02 filler pic x value ascii-escape. 02 filler pic x value "\". 01 gss-record. 02 filler pic x value ascii-escape. 02 filler pic x value "[". 02 gss-type-size pic 999. 02 filler pic x(2) value " C". 01 hpa-record. 02 filler pic x value ascii-escape. 02 filler pic x(3) value "[1`". 01 pfs-landscape-record. 02 filler pic x value ascii-escape. 02 filler pic x(6) value "[?21 J". 01 pfs-portrait-record. 02 filler pic x value ascii-escape. 02 filler pic x(6) value "[?20 J". 01 ris-record. 02 filler pic x value ascii-escape. 02 filler pic x value "c". 01 sgr-dbultn1-record. 02 filler pic x value ascii-escape. 02 filler pic x(4) value "[10m". 01 sgr-rcourir-record. 02 filler pic x value ascii-escape. 02 filler pic x(4) value "[11m". 01 sgr-relite0-record. 02 filler pic x value ascii-escape. 02 filler pic x(4) value "[12m". 01 spi-record. 02 filler pic x value ascii-escape. 02 filler pic x value "[". 02 spi-vertical-pitch pic 999. 02 filler pic x value ";". 02 spi-horizontal-pitch pic 999. 02 filler pic x(2) value " G". 01 vpa-record. 02 filler pic x value ascii-escape. 02 filler pic x(3) value "[1d". 01 switches. 02 aux-file-requested-sw pic x value "F". 88 aux-file-requested value "T". 02 control-parameters-are-ok-sw pic x. 88 control-parameters-are-ok value "T". 02 eof-sw pic x value "F". 88 eof value "T". 02 modified-format-requested-sw pic x. 88 modified-format-requested value "T". 02 statistics-requested-sw pic x value "T". 88 statistics-requested value "T". PROCEDURE DIVISION. Enpage-a-file. perform 1-get-control-parameters perform 2-edit-control-parameters if control-parameters-are-ok then subtract 1 from top-margin giving top-margin-minus-one perform 3-open-input-file perform c-1-read-line perform 4-create-new-page until eof perform 5-close-files if statistics-requested perform 6-display-statistics end-if else display "Invalid parameters. No data processed." display "Parameters must be:" display " LEFT-MARGIN TOP-MARGIN MAX-LINES STATS-FLAG AUX-FILE-FLAG" display " VERTICAL-PITCH HORIZONTAL-PITCH PAGE-FORMAT TYPE-FAMILY TYPE-SIZE." display "Defaults are: 10 6 55 T F 0 0 0 0 0." end-if stop run . 1-get-control-parameters. call "lib$get_foreign" using by descriptor input-parameters by value zero by reference input-parameters-length by value zero * I would use reference modification, but COBOL won't let me. unstring input-parameters delimited by spaces into input-param-left-margin input-param-top-margin input-param-max-lines input-param-stats-requested input-param-aux-file-requested input-param-vertical-pitch input-param-horizontal-pitch input-param-page-format input-param-type-family input-param-type-size input-param-tab-size if input-param-left-margin not = spaces then call "ots$cvt_ti_l" using by descriptor input-param-left-margin by reference left-margin by value longword-size-in-bytes by value ignore-blanks-and-tabs end-if if input-param-top-margin not = spaces then call "ots$cvt_ti_l" using by descriptor input-param-top-margin by reference top-margin by value longword-size-in-bytes by value ignore-blanks-and-tabs end-if if input-param-max-lines not = spaces then call "ots$cvt_ti_l" using by descriptor input-param-max-lines by reference maximum-lines-per-page by value longword-size-in-bytes by value ignore-blanks-and-tabs end-if if input-param-stats-requested not = spaces then move input-param-stats-requested ( 1 : 1 ) to statistics-requested-sw end-if if input-param-aux-file-requested not = spaces then move input-param-aux-file-requested ( 1 : 1 ) to aux-file-requested-sw end-if if input-param-vertical-pitch not = spaces then * Convert it to a d-floating (comp-2) data item. call "ots$cvt_t_d" using by descriptor input-param-vertical-pitch by reference d-floating-hold-variable by value zero by value zero by value ignore-blanks-and-tabs by reference extra-precision-bits move d-floating-hold-variable to vertical-pitch end-if if input-param-horizontal-pitch not = spaces then * Convert it to a d-floating (comp-2) data item. call "ots$cvt_t_d" using by descriptor input-param-horizontal-pitch by reference d-floating-hold-variable by value zero by value zero by value ignore-blanks-and-tabs by reference extra-precision-bits move d-floating-hold-variable to horizontal-pitch end-if if input-param-page-format not = spaces then move input-param-page-format ( 1 : 1 ) to page-format-flag end-if if input-param-type-family not = spaces then move input-param-type-family to type-family end-if if input-param-type-size not = spaces then * Convert it to a d-floating (comp-2) data item. call "ots$cvt_t_d" using by descriptor input-param-type-size by reference d-floating-hold-variable by value zero by value zero by value ignore-blanks-and-tabs by reference extra-precision-bits move d-floating-hold-variable to type-size end-if if input-param-tab-size not = spaces then call "ots$cvt_ti_l" using by descriptor input-param-tab-size by reference tab-size by value longword-size-in-bytes by value ignore-blanks-and-tabs end-if if vertical-pitch = zero and horizontal-pitch = zero and page-format-flag = page-format-unchanged-k and type-family = type-family-unchanged-k and type-size = zero then move ws-false to modified-format-requested-sw else move ws-true to modified-format-requested-sw end-if . 2-edit-control-parameters. if left-margin not < zero and top-margin not < zero and maximum-lines-per-page not < 1 and ( statistics-requested-sw = ws-false or statistics-requested-sw = ws-true ) and ( aux-file-requested-sw = ws-false or aux-file-requested-sw = ws-true ) and vertical-pitch not < zero and horizontal-pitch not < zero and ( page-format-flag = page-format-unchanged-k or page-format-flag = page-format-portrait-k or page-format-flag = page-format-landscape-k ) and ( type-family = type-family-unchanged-k or type-family = type-family-dbultn1-k or type-family = type-family-rcourir-k or type-family = type-family-relite0-k ) and ( type-size = 0 or type-size = 6.7 or type-size = 10 ) and tab-size > 0 then move ws-true to control-parameters-are-ok-sw else move ws-false to control-parameters-are-ok-sw end-if . 3-open-input-file. open input input-file . 4-create-new-page. add 1 to output-page-count perform 4-1-create-top-margin move 1 to next-text-line-on-page perform 4-2-create-new-line until eof or next-text-line-on-page > maximum-lines-per-page . 4-1-create-top-margin. evaluate output-page-count when 1 open output output-file-1 move 1 to current-output-file move zero to output-record-length if modified-format-requested then perform 4-1-1-set-modified-format end-if when 2 if aux-file-requested then open output output-file-2 move 2 to current-output-file move zero to output-record-length if modified-format-requested then perform 4-1-1-set-modified-format end-if else move formfeed-char to output-record-1 ( 1 : 1 ) move 1 to output-record-length end-if when other move formfeed-char to output-record-1 ( 1 : 1 ) move 1 to output-record-length end-evaluate if top-margin > zero then perform c-2-write-line move zero to output-record-length perform c-2-write-line top-margin-minus-one times ** else ** preserve whatever formatting info was loaded into the output-record end-if . 4-1-1-set-modified-format. * Reset the laser printer to it's initial state. add 1 to output-record-length giving tmp-next-char move ris-record to output-record-1 ( tmp-next-char : ris-record-size ) add ris-record-size to output-record-length * Make sure there's room in laser memory for whatever we're about to do. add 1 to output-record-length giving tmp-next-char move declff-erase-fonts-record to output-record-1 ( tmp-next-char : declff-erase-fonts-record-size ) add declff-erase-fonts-record-size to output-record-length evaluate page-format-flag when page-format-unchanged-k continue when page-format-portrait-k add 1 to output-record-length giving tmp-next-char move pfs-portrait-record to output-record-1 ( tmp-next-char : pfs-portrait-record-size ) add pfs-portrait-record-size to output-record-length when page-format-landscape-k add 1 to output-record-length giving tmp-next-char move pfs-landscape-record to output-record-1 ( tmp-next-char : pfs-landscape-record-size ) add pfs-landscape-record-size to output-record-length when other display "Internal error - unexpected page-format being ignored." end-evaluate evaluate type-family when type-family-unchanged-k continue when type-family-dbultn1-k add 1 to output-record-length giving tmp-next-char move sgr-dbultn1-record to output-record-1 ( tmp-next-char : sgr-record-size ) add sgr-record-size to output-record-length when type-family-rcourir-k add 1 to output-record-length giving tmp-next-char move sgr-rcourir-record to output-record-1 ( tmp-next-char : sgr-record-size ) add sgr-record-size to output-record-length when type-family-relite0-k add 1 to output-record-length giving tmp-next-char move sgr-relite0-record to output-record-1 ( tmp-next-char : sgr-record-size ) add sgr-record-size to output-record-length when other display "Internal error - unexpected type-family being ignored." end-evaluate if type-size not = zero then multiply type-size by 10 giving gss-type-size add 1 to output-record-length giving tmp-next-char move gss-record to output-record-1 ( tmp-next-char : gss-record-size ) add gss-record-size to output-record-length end-if if vertical-pitch not = zero or horizontal-pitch not = zero then if vertical-pitch = zero then move zero to spi-vertical-pitch else divide decipoints-per-inch by vertical-pitch giving spi-vertical-pitch rounded end-if if horizontal-pitch = zero then move zero to spi-horizontal-pitch else divide decipoints-per-inch by horizontal-pitch giving spi-horizontal-pitch rounded end-if add 1 to output-record-length giving tmp-next-char move spi-record to output-record-1 ( tmp-next-char : spi-record-size ) add spi-record-size to output-record-length end-if * Make sure we start at line 1. add 1 to output-record-length giving tmp-next-char move vpa-record to output-record-1 ( tmp-next-char : vpa-record-size ) add vpa-record-size to output-record-length * Make sure we start at column 1. add 1 to output-record-length giving tmp-next-char move hpa-record to output-record-1 ( tmp-next-char : hpa-record-size ) add hpa-record-size to output-record-length . 4-2-create-new-line. add 1 to output-line-count call "str$trim" using by descriptor input-record ( 1 : input-record-length ) by descriptor input-record ( 1 : input-record-length ) by reference input-record-length if input-record-length = zero or input-record ( 1 : 1 ) not = formfeed-char then move 1 to next-input-char else move 2 to next-input-char end-if subtract next-input-char from input-record-length giving remaining-input-chars add 1 to remaining-input-chars if top-margin > zero or next-text-line-on-page > 1 then move spaces to output-record-1 ( 1 : left-margin ) add 1 to left-margin giving next-output-char else add 1 to output-record-length giving tmp-next-char move spaces to output-record-1 ( tmp-next-char : left-margin ) add output-record-length, left-margin, 1 giving next-output-char end-if move zero to tab-offset perform until remaining-input-chars = zero perform 4-2-1-copy-normal-chars if remaining-input-chars > zero then perform 4-2-2-emulate-horizontal-char end-if end-perform subtract 1 from next-output-char giving output-record-length if output-record-1 ( output-record-length : 1 ) = space then call "str$trim" using by descriptor output-record-1 ( 1 : output-record-length ) by descriptor output-record-1 ( 1 : output-record-length ) by reference output-record-length end-if perform c-2-write-line perform c-1-read-line if input-record-length > zero and input-record ( 1 : 1 ) = formfeed-char then add 1 to maximum-lines-per-page giving next-text-line-on-page else add 1 to next-text-line-on-page end-if . 4-2-1-copy-normal-chars. call "lib$scanc" using by descriptor input-record ( next-input-char : remaining-input-chars ) by reference horizontal-formatting-chars by reference scanc-mask giving horiz-formatting-char-offset if horiz-formatting-char-offset = zero then move remaining-input-chars to normal-char-count else subtract 1 from horiz-formatting-char-offset giving normal-char-count end-if move input-record ( next-input-char : normal-char-count ) to output-record-1 ( next-output-char : normal-char-count ) add normal-char-count to next-input-char subtract normal-char-count from remaining-input-chars add normal-char-count to next-output-char add normal-char-count to tab-offset divide tab-offset by tab-size giving signed-longword-hold-variable remainder tab-offset . 4-2-2-emulate-horizontal-char. evaluate input-record ( next-input-char : 1 ) when tab-char subtract tab-offset from tab-size giving fill-spaces-required move spaces to output-record-1 ( next-output-char : fill-spaces-required ) add fill-spaces-required to next-output-char move zero to tab-offset add 1 to next-input-char subtract 1 from remaining-input-chars when backspace-char * Collapse space-plus-backspace pairs. subtract 1 from next-output-char giving tmp-prior-char if next-output-char > 1 and output-record-1 ( tmp-prior-char : 1 ) = space then subtract 1 from next-output-char add 1 to next-input-char subtract 1 from remaining-input-chars else perform c-3-copy-one-char end-if if tab-offset = zero then subtract 1 from tab-size giving tab-offset else subtract 1 from tab-offset end-if when escape-char perform c-3-copy-one-char if remaining-input-chars > zero then perform 4-2-2-1-emulate-escape-sequence else add 1 to unknown-horizontal-char-count end-if when other add 1 to unknown-horizontal-char-count perform c-3-copy-one-char end-evaluate . 4-2-2-1-emulate-escape-sequence. evaluate input-record ( next-input-char : 1 ) when "[" perform c-3-copy-one-char with test after until remaining-input-chars = zero or ( input-record ( next-input-char : 1 ) is not numeric and input-record ( next-input-char : 1 ) not = ";" ) if remaining-input-chars > zero then evaluate input-record ( next-input-char : 1 ) * Is it a select-graphic-rendition (SGR) escape sequence? when "m" continue when other add 1 to unknown-horizontal-char-count end-evaluate perform c-3-copy-one-char else add 1 to unknown-horizontal-char-count end-if when other add 1 to unknown-horizontal-char-count perform c-3-copy-one-char end-evaluate . 5-close-files. if modified-format-requested then move current-output-file to hold-current-output-file perform 5-1-reset-modified-format perform c-2-write-line varying current-output-file from 1 by 1 until current-output-file > hold-current-output-file move hold-current-output-file to current-output-file end-if evaluate current-output-file when 0 display "No output file created." when 1 close output-file-1 when 2 close output-file-1 close output-file-2 when other display "Internal error: unknown output file in 5" end-evaluate close input-file . 5-1-reset-modified-format. move zero to output-record-length * I would clean up laser memory here, just like I do in 4-1-1, but * erasing the font that I just used forces an extra page to eject. evaluate page-format-flag when page-format-unchanged-k continue when page-format-portrait-k continue when page-format-landscape-k * Portrait is the initial (though not the default) page format add 1 to output-record-length giving tmp-next-char move pfs-portrait-record to output-record-1 ( tmp-next-char : pfs-portrait-record-size ) add pfs-portrait-record-size to output-record-length when other display "Internal error - unexpected page-format can't be reset." end-evaluate evaluate type-family when type-family-unchanged-k continue when type-family-dbultn1-k continue when type-family-rcourir-k * DBULTN1 is the default page format add 1 to output-record-length giving tmp-next-char move sgr-dbultn1-record to output-record-1 ( tmp-next-char : sgr-record-size ) add sgr-record-size to output-record-length when type-family-relite0-k * DBULTN1 is the default page format add 1 to output-record-length giving tmp-next-char move sgr-dbultn1-record to output-record-1 ( tmp-next-char : sgr-record-size ) add sgr-record-size to output-record-length when other display "Internal error - unexpected type-family can't be reset." end-evaluate if type-size not = zero then move 100 to gss-type-size add 1 to output-record-length giving tmp-next-char move gss-record to output-record-1 ( tmp-next-char : gss-record-size ) add gss-record-size to output-record-length end-if if vertical-pitch not = zero or horizontal-pitch not = zero then move zero to spi-vertical-pitch move zero to spi-horizontal-pitch add 1 to output-record-length giving tmp-next-char move spi-record to output-record-1 ( tmp-next-char : spi-record-size ) add spi-record-size to output-record-length end-if . 6-display-statistics. move output-page-count to display-count display "Pages processed:" display-count move output-line-count to display-count display "Lines processed:" display-count if unknown-horizontal-char-count > zero then move unknown-horizontal-char-count to display-count display display-count " unknown horizontal-formatting characters encountered." end-if . c-1-read-line. read input-file at end move ws-true to eof-sw end-read . c-2-write-line. evaluate current-output-file when 1 write output-record-1 when 2 write output-record-2 when other display "Internal error: unknown output file in C-2" end-evaluate . c-3-copy-one-char. move input-record ( next-input-char : 1 ) to output-record-1 ( next-output-char : 1 ) add 1 to next-output-char add 1 to next-input-char subtract 1 from remaining-input-chars .