Using pagedjs with Svelte
Hi! Thanks for developing pagedjs.
I have successfully used the polyfill to transform a html page to a nice PDF.
I am struggling however how to use the npm-module in an application built with Svelte (I also see a similar question about usage with Angular #56 ). I can get something out but it is very unpredictable, eg. I might get 800 pages (instead of expected 29). I honestly don't really know what I am doing.
The example provided in README.md is very basic and lacks information regarding types, and the sample pages in /examples are also all in .html and not Svelte/React/Vue/Angular
import { Previewer } from 'pagedjs';
let paged = new Previewer();
let flow = paged.preview(DOMContent, ["path/to/css/file.css"], document.body).then((flow) => {
console.log("Rendered", flow.total, "pages.");
})
What are DOMContents even? What type? And what is the role of the css-file? Why do you need to inject it here?
Is it even possible to "embed" a pagedjs "sandbox" within a broader application (eg. built with Svelte) without affecting the rest of the application? Is it possible to have a fixed element with all kinds of javascript living "outside" of the pagedjs context? Or should I always isolate the pagedjs-page on a route of its own?
Anyone have a example repo with pagedjs and Svelte? (not using polyfill)
I hope I am not alone!
Hi @einarpersson
@fchasen is away for a bit so my answer may be a bit sparse.
an example of how pagedjs work with the polyfill here:
so if i recall, in
let flow = paged.preview(DOMContent, ["path/to/css/file.css"], document.body).then((flow) => {
DOMContent is the html you want to paginate.
pathToCssFile is the link to the css you want to use for the pagination
document.body is the element your paginated content will appear in.
The path to css file can also be a string with the content of your css.
Until Pagedjs.0.4.1beta (which is not out yet), we pushed toward using the polyfill in an iframe (not ideal, but the contents and the styles were correctly separated from your main content). We need to revisit some previous examples and make some new. I guess i’ll check how svelte works for a simple demo.
on the: > might get 800 pages (instead of expected 29
I would say that there is a content looping somewhere (either an error in the css, or the html not being friendly).
Does that help a little?
Thanks @julientaq for your answer!
Of what type is DOMContent supposed to be? Is it a DocumentFragment? Please add this to documentation since "html" is a bit ambiguous.
--
Anyway, I think I'll stick to just presenting my document in Svelte/html (without pagedjs) and only include the pagedjs polyfill when the user wants to create a printer friendly version or save as PDF.
(But I encourage you to anyhow checkout Svelte since it is very nice to work with imo:) )
Of what type is DOMContent supposed to be? Is it a DocumentFragment? Please add this to documentation since "html" is a bit ambiguous.
Agreed. Somehow, html got much more meaning that what it had originaly.
Anyway, I think I'll stick to just presenting my document in Svelte/html (without pagedjs) and only include the pagedjs polyfill when the user wants to create a printer friendly version or save as PDF.
I think that should be the best way to share a content. HTML is always better than PDF, but not always better than print).
I did a small app to show how you could use paged.js (the polyfill) in a environment for customizable prints. You may want to have a look: http://www.lesvoisinsdustudio.ch/hybrid/hybrid.html (hit the pagejs button top left) and you can check the code here: https://gitlab.coko.foundation/pagedjs/parametricpagedjs
I should make a plugin/extension out of this.
And yes, i’ll have a look at svelte :)
This is more or less how I'm using pagedjs in svelete (simplified longer code so not sure if it compiles):
<script>
import { afterUpdate } from "svelte";
import { Previewer } from "pagedjs";
import { throttle } from "lodash";
let cssString = `
.print-footer {
position: running(print-footer);
}
@page {
@bottom-right {
font-size: 10pt;
color: var(--sl-color-neutral-500);
content: counter(page) "/" counter(pages);
}
@bottom-center {
content: element(print-footer);
color: var(--sl-color-neutral-500);
font-size: 0.8em;
width: 70mm;
}
}
`;
export let html;
let previewElem;
const previewer = new Previewer();
function preview(html) {
if (html && previewElem) {
previewer.preview(html, [{ _: cssString }], previewElem)
.then(flow => {
console.log("preview rendered, total pages", flow.total, { flow });
console.log("performance: ", flow.performance)
});
}
}
const throttledPreview = throttle(preview, 1000);
afterUpdate(() => throttledPreview(html));
</script>
<div class="container">
<div class="toolbar">
Toolbar
</div>
<div class="page-container">
<div id="print-preview" bind:this={previewElem} />
</div>
</div>
<style>
p {
text-align: justify;
}
</style>
where the html prop can be something like this:
let html = `
<div class="doc">
<p class="print-footer">footer </p>
<h5>Hello World</h5>
<p>
Hi there
</p>
</div>
`;
Note the previewElem var it's where generated content gets inserted.