Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

auto page enumeration

Status
Not open for further replies.

rborysov

Programmer
Dec 17, 2003
5
UA
I'm trying to generate some reports in Postscript from my C++ program. When the report exceeds one page I need properly insert "%%Page: label NUMBER" comment into the ps-file. Starting generating the ps-file I don't know the total number of pages. I attemped to declare

/currpagenumber 1 def

and use it in the comment

%%Page: label currpagenumber

but the PS interpreter expects an ordinal integer constant instead of my currpagenumber.

If total page number is a priori unknown, how should one enumerate a multipage document in Postscript?

I'll be grateful for any assistance.

Roman

 
Roman,

Why do you need these comments? You only need to insert the comments if you're trying to write a DSC-compliant PostScript program, and you only need to do that if the PostScript will be part of a DSC workflow.

A DSC workflow means that the PostScript will be consumed prior to actual interpretation, by a machine or software program that performs some job control function, such as sending some pages to paper tray 1 and others to paper tray 2. Or the output device may need to print the PostScript file backwards and face-up... DSC comments allow for a workflow management/job management program to process meta-data about the program without having to interpret it first.

My point is that DSC comments are NOT required by an actual PostScript interpreter. The reason that your statement:

%%Page: label currpagenumber

doesn't mean anything to the interpeter is because, as it is simply a comment, the interpreter ignores it completely.

If you must, in spite of all of the above, absolutely have these comments in your code, put them in with your C program. DSC allows you to put anything you don't know yet "atend" as in "at the end of the document".

So for the opening "%%Pages:" comment, just put

Code:
%%Pages: (atend)

Then for your actual Page comments, you can do something like this:

Code:
%%Page: 1 1

The first "1" is a label and the second is, as you say, an ordinal number. Page 2 would be %%Page: 2 2, and so on. Again, you'll have to maintain a counter in your C++ program to output these comments as you go.

Then, at the end of your document, in the %%Trailer section, put your final page count: "%%Pages: 2".

Hope this helps.

Thomas D. Greer
 
Tomas,

Of course, I can trace PS currentpoint in my C program.
For this I need repeatedly perform some transformations, e.g. number of text lines (of various fonts) and borders of table to PS points. Nevertheless, I think such an approch will work.
Thank you.

I was interested in continious writing my rows of the report table to a ps-file. After each row written some PS procedure could be check the validity of the currentpoint and insert proper %%Page comment if necessary. Obviously, this idea was incorrect. Sorry.

Roman.
 
Ah, I see. A clever approach! Unfortunately, PostScript can't write to itself. There is a currentfile operator that allows you to read from the currentfile... but I don't think you can't write a statement back into itself, which is what you need to do to create a comment line.

You can of course use your "source" PostScript program to write a second "final" PostScript program. For every PostScript "line" in your source, copy it into a string and write it out to your final file. Then execute the string and your currentpoint procedure. If it needs a new page, then write the comments out to your final file.

This is cumbersome and I haven't thought it through completely, but may allow you to do pagination through PostScript rather than C++.

Again, though, DSC comments should be ignored by a valid PostScript interpreter.

I want to make sure you understand this point. If you want to force a "new page" if your currentpoint reaches a certain level, you know that you can conditionally use "showpage", right?

Code:
currentpoint exch pop  % leave "y" on stack
36 le                  % y less than or = 1/2 inch
{ showpage
  % perform any "page setup" commands
}
{ % not at bottom, keep going
} ifelse

The showpage will create a new page. You don't need the comment; the comment doesn't "make" a new page, showpage does.

Thomas D. Greer
 
Tomas,

your code with showpage works. And I don't trace PS currentpoint in my C program. But there is the last problem I couldn't solve. If a table in my generated report is multipage, I should redraw the table header on new page.
Of course, drawing this header first time, I can save it to a file. Then content of the file may be placed at the beginning of a new page.

Explain me please, how insert the content of some ps-file into another.

Thank you,
Roman
 
Roman,

You can do this with the "run" operator. It takes a string as an argument. If you need to pass a complete path with slashes, you have to escape the slashes:

Code:
(c:\\MyFolder\\MySubFolder\\MyProgram.ps) run

Of course, the most efficient way to do what you want is with a PostScript procedure. Embed all of your instructions to draw the table header into a procedure:

Code:
/myHeader
{ % code to make header goes here
} bind def

Then you can call it whenever you like, just like you do with methods/procedures in C, right? So your PostScript code output might look like this:

Code:
%!PS

/myHeader
{ % all header code here
} bind def

myHeader  % draw the header

{ % endless loop to draw table rows
  % draw a row
  % test to see if at bottom of page
  currentpoint exch pop  % leave "y" on stack
  36 le                  % y less than or = 1/2 inch
  { showpage
    myHeader   % new page, so do header again
  }
  { % not at bottom, keep going
  } ifelse

  % test to see if all rows processed, if so
  % use "exit" to quit the loop
} loop

The actual structure I use for situations like this is to write out PostScript procedures at the top of the program, and all my data at the bottom, in an array or dictionary.

Example structure:

Code:
%!PS

/drawTableHeader
{ %code
} bind def

/drawTableRow
{ % code for single row
} bind def

/testPosition
{ % code to see where I'm at on the page, do showpage
  % whatever else needed
} bind def

/drawPage
{ % main procedure which consumes data

  drawTableHeader  %draw first header
  
  % "rows" is on stack, loop through each row with forall
  { drawRow
    testPosition 
  } forall
} bind def
%% END OF PROCEDURES
%% BEGIN DATA
/rows
[ (row1)
  (row2)
  (row3)
] def
%% END DATA
drawPage   % call the main procedure


Thomas D. Greer
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top