The application I'm writing uses libcairo to output vector graphics; everything works fine for output formats that support multiple pages (PDF, PostScript), however I would also like to support SVG and bitmap formats.
Currently, I just click pages with showPage whenever I otherwise overflow the bottom edge and I would like the code to be structured this way. I came up with two theoretically possible solutions:
a) An auxiliary monad that goes around the Cairo Render monad, but provides a flushPage action, which, when chained to it, flushPage current Render action on the stack of the internal page, performs the liftRender action, which, well, raise the Render action to the monad, binding it to the previously buffered an action and a helper function to retrieve the list of Render () actions, one for each page. So I would just call my main rendering function, but instead of the Render () action, it would return the pagination-wrapper action, from which I would then extract individual pages and process them - for multi-page formats, I could just chain them together by inserting the showPage actions between them, while for single-page formats, I would do them individually. As an example, here's how it would look:
-- original code renderMe :: Render () renderMe = do newPath moveTo 10 10 lineTo 20 20 lineTo 10 30 lineTo 10 10 fill showPage newPath moveTo 10 10 lineTo 20 20 lineTo 10 30 lineTo 10 10 fill -- new code renderPages :: PagedRender () renderPages = do liftRender (do newPath moveTo 10 10 lineTo 20 20 lineTo 10 30 lineTo 10 10 fill) flushPage liftRender (do newPath moveTo 10 10 lineTo 20 20 lineTo 10 30 lineTo 10 10 fill) flushPage
b) A cairo surface type that acts as a multi-page document from the outside, but creates a series of one-page documents from the outside. This would be ideal, since it would not require any changes in the rendering code at all, but I'm not sure that this can be done without delving into cairo itself at the initial level.
So, the actual question is: Is there any of the above solutions? As in any case, did anyone write either a "page wrapper nonsense" or a "multi-page SVG surface"? And in the case of the answer "no"; which one is preferable, and how are you going to implement it?