mdpdf icon indicating copy to clipboard operation
mdpdf copied to clipboard

Trying to add Page Number in the footer

Open DEYROS opened this issue 3 years ago • 45 comments

I'm trying to add a page number in the footer of my PDF.

index.js that I run(node) to create the PDF:

const path = require('path');
const mdpdf = require('mdpdf');

const options = {
	source: path.join("examples/api/", 'fichierConcatDoitAvoir.md'), 
	destination: path.join("examples/api/", 'pdf-file.pdf'), 
	styles: path.join("examples/api/", 'styles.css'), 
	ghStyle: false,
	defaultStyle: true,
	footer: path.join("examples/api/", 'footer.html'),
	header: path.join("examples/api/", 'header.html'),
	pdf: {
		format: 'A4', 
		orientation: 'portrait',
		quality: '100',
		header: {
			height: '25mm'
		},
		footer: {
			height: '17mm'
		},
		border: {
			top: '10mm',
			left: '20mm',
			bottom: '5mm',
			right: '20mm'
		},
	}
};

// Call convert which returns a thenable promise with the pdfPath
mdpdf.convert(options).then(pdfPath => {
	console.log('Fichier PDF créé :', pdfPath);
}).catch(err => {
    // Don't forget to handle errors
	console.error(err);
});

The footer that I have created in HTML :

<footer>
    <div id="footer">
        <h1 class="txt">SpringCard</h1>
        <hr class="solid">
        <div class="nbPages">Page <span class="pageNumber">?</span>/ <span class="totalPages ">4</span></div>
    </div>
</footer>

I think I'm not supposed to write "?" or even "4" but it is so that you understand well what I expect. Here is what I got : image I think that I have to use puppeteer but I don't know/understand how. Thx !

DEYROS avatar Jun 15 '22 13:06 DEYROS

I think I'm not supposed to write "?" or even "4" but it is so that you understand well what I expect.

Just to clarify, does this mean you've tried using it without specifying those values? Such as:

<div class="nbPages">Page <span class="pageNumber"></span>/<span class="totalPages"></span></div>

Would it be possible to try a div rather than a span for those as well and see what happens?

elliotblackburn avatar Jun 15 '22 13:06 elliotblackburn

I tried it and nothing happened : image And if i try a div rather than a span these happen : image

<footer>
    <div id="footer">
        <h1 class="txt">SpringCard</h1>
        <hr class="solid">
        <div class="nbPages">Page <div class="pageNumber"></div>/ <div class="totalPages "></div></div>
    </div>
</footer>

DEYROS avatar Jun 15 '22 14:06 DEYROS

<footer>
	<div id="footer">
		<h1 class="txt">SpringCard</h1>
		<hr class="solid">
		<div class="nbPages">Page <span class="pageNumber"></span>/ <span class="totalPages ">4</span></div>
	</div>
</footer>

This works for me

Are you sure you properly saved your file

nopeless avatar Jun 23 '22 15:06 nopeless

hello @nopeless how did you create the pdf ? Like me or with puppeteer ? Could you please show me how did you did it ? Thx !

DEYROS avatar Jun 23 '22 18:06 DEYROS

hello @nopeless how did you create the pdf ? Like me or with puppeteer ? Could you please show me how did you did it ? Thx !

Its just your code. It worked first try. Would you like a stackblitz (free repo hosting website) for reproduction?

nopeless avatar Jun 23 '22 18:06 nopeless

Nothing else really ? Yes it would be perfect thx

DEYROS avatar Jun 23 '22 18:06 DEYROS

GitPod*

I have no idea why the machine in GitPod can't install some libraries (can't run puppeteer) but use this code

const path = require('path');
const mdpdf = require('./src/index.js');

const options = {
	source: "test.md", 
	destination: "test.pdf", 
	footer: 'footer.html',
	pdf: {
		format: 'A4', 
		orientation: 'portrait',
		quality: '100',
		header: {
			height: '25mm'
		},
		footer: {
			height: '17mm'
		},
		border: {
			top: '10mm',
			left: '20mm',
			bottom: '5mm',
			right: '20mm'
		},
	}
};

// Call convert which returns a thenable promise with the pdfPath
mdpdf.convert(options).then(pdfPath => {
	console.log('Fichier PDF créé :', pdfPath);
}).catch(err => {
    // Don't forget to handle errors
	console.error(err);
});

footer.html

<footer>
	<div id="footer">
		<h1 class="txt">SpringCard</h1>
		<hr class="solid">
		<div class="nbPages">Page <span class="pageNumber" style="font-size: 50px"></span>/ <span class="totalPages ">4</span></div>
	</div>
</footer>

@DEYROS

nopeless avatar Jun 23 '22 19:06 nopeless

oh and uh... You might have to use path.join again (this code is tested on a custom branch #119) and this pr fixes path resolve

nopeless avatar Jun 23 '22 19:06 nopeless

Ok ok could you make a screenshot of the pages ? To see what you get ?

DEYROS avatar Jun 23 '22 19:06 DEYROS

@DEYROS image

nopeless avatar Jun 24 '22 02:06 nopeless

When I try to use your code here is what happen :

Error: Cannot find module './src/index.js'
Require stack:
- D:\aperrot\markdowntopdf\index.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (D:\aperrot\markdowntopdf\index.js:2:15)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ 'D:\\aperrot\\markdowntopdf\\index.js' ]

DEYROS avatar Jun 24 '22 07:06 DEYROS

@nopeless Why did you put :

const mdpdf = require('./src/index.js');

instead of :

const mdpdf = require('mdpdf');

That's maybe why it doesn't work for me.

DEYROS avatar Jun 24 '22 08:06 DEYROS

I also tried something like that :

const path = require('path');
const mdpdf = require('mdpdf');

// Configure les différentes options
const options = {
	source: 'ConcatSpringCore.md', //Le fichier à transformer en PDF DOIT ETRE DANS LE MEME QUE CELUI CREE
	destination:'pdfFinal.pdf', //Le fichier PDF qui sera créé
	footer: 'footer.html',//Le bas de page
	header: 'header.html',//Le haut de page
	pdf: {
		format: 'A4', 
		orientation: 'portrait',
		quality: '100',
		header: {
			height: '25mm'
		},
		footer: {
			height: '17mm'
		},
		border: {
			top: '1mm',
			left: '20mm',
			bottom: '5mm',
			right: '20mm'
		},
	}
};

// Call convert which returns a thenable promise with the pdfPath
mdpdf.convert(options).then(pdfPath => {
	console.log('Fichier PDF créé :', pdfPath);
}).catch(err => {
    // Don't forget to handle errors
	console.error(err);
});

and for my footer.html :

<footer>
	<div id="footer">
		<h1 class="txt">SpringCard</h1>
		<hr class="solid">
		<div class="nbPages">Page <span class="pageNumber" style="font-size: 50px"></span>/ <span class="totalPages ">4</span></div>
	</div>
</footer>

And I got this : image So it doesn't work

DEYROS avatar Jun 24 '22 09:06 DEYROS

@nopeless Why did you put :

const mdpdf = require('./src/index.js');

instead of :

const mdpdf = require('mdpdf');

That's maybe why it doesn't work for me.

Because I am running this code on a clone of this repo. Let me test something real quick

nopeless avatar Jun 24 '22 11:06 nopeless

OK ok thx

DEYROS avatar Jun 24 '22 11:06 DEYROS

@DEYROS I am totally unable to replicate your issue. Can you upload an entire zip file here or create a new repository containing all source code? My best guess is that your CSS is causing issues but this entire thread was beating around the bush and I want to nail it down this time

nopeless avatar Jun 24 '22 11:06 nopeless

No problem, here it is : pdfFinal.zip Thnak you for your help !

DEYROS avatar Jun 24 '22 11:06 DEYROS

I deleted the css from the index.js :

styles: 'styles.css',

This line. It doesn't work, I don't have any page numbers. So I don't think the problem come from the css

DEYROS avatar Jun 24 '22 11:06 DEYROS

@DEYROS General tip: when people ask u to send a zip for node project, include package.json and package-lock.json

nopeless avatar Jun 24 '22 12:06 nopeless

Sorry for that, here it is pdfFinal.zip

DEYROS avatar Jun 24 '22 12:06 DEYROS

I tried running your poject and for some reason the footer appears squished

Nonetheless, the page number is still there

image

I think it might be a puppeteer issue. What is your puppeteer version?

nopeless avatar Jun 24 '22 12:06 nopeless

I have just done an "npm i puppeteer" so I should have the last version ?

DEYROS avatar Jun 24 '22 12:06 DEYROS

npm list puppeteer
(async()=>{const x = require("puppeteer"); console.log(await(await(await x.launch()).newPage()).browser().version())})()

I have 8.13.0 and HeadlessChrome/80.0.3987.0 what about you

nopeless avatar Jun 24 '22 12:06 nopeless

Could you please explain me how did you execute the index.js(node index.js or you create a script into package.json?) and where he is into your folder ?

DEYROS avatar Jun 24 '22 12:06 DEYROS

Puppeteer is a dependency of mdpdf, so you don't need to install it seperately. I've pushed a branch with the latest puppeteer because we're very far behind.

Using mdpdf via cli (npm install -g mdpdf)

If you uninstall mdpdf globally npm uninstall -g mdpdf, pull this branch https://github.com/BlueHatbRit/mdpdf/pull/123 and then run npm install && npm link you'll pull down all the latest dependencies including my puppeteer upgrade. You'll also have mdpdf linked to your global installation so you can run it from the command line.

Using mdpdf via the js api

If you're using mdpdf in a nodejs project using a package.json you can use git://github.com/bluehatbrit/mdpdf.git#puppeteer-upgrade instead of the mdpdf version number and run an npm install which will pull in my branch.

You can then run the code provided by @nopeless to see if there's any difference.

elliotblackburn avatar Jun 24 '22 12:06 elliotblackburn

Could you please explain me how did you execute the index.js(node index.js or you create a script into package.json?) and where he is into your folder ?

That is just mdpdf's index.js. I ran the script in a clone of this repo and src/index.js should be identical to mdpdf in most cases

nopeless avatar Jun 24 '22 12:06 nopeless

image The problem maybe come from my node_modules ? I have installed a lot of libraries how could I start from the begining(clear everything) and then install only mdpdf ? If I delete "node_modules" what happen ? What does this file do exactly ? Curently I have all this files open in vsCode and I execute index.js with node index.js in the integrated terminal : image

DEYROS avatar Jun 24 '22 13:06 DEYROS

image The problem maybe come from my node_modules ? I have installed a lot of libraries how could I start from the begining(clear everything) and then install only mdpdf ? If I delete "node_modules" what happen ? What does this file do exactly ? Curently I have all this files open in vsCode and I execute index.js with node index.js in the integrated terminal : image

node_modules is just how node manages external libraries

you should NOT delete that folder

nopeless avatar Jun 24 '22 13:06 nopeless

If you're using the js api (as you seem to be with a node project) you should open your package.json and replace the mdpdf line's version number with git://github.com/bluehatbrit/mdpdf.git#puppeteer-upgrade. Then run npm install on the command line and re-run your code. That will put you on the experimental branch where I have just upgraded Puppeteer in mdpdf.

elliotblackburn avatar Jun 24 '22 13:06 elliotblackburn

image image I should replace that :

"mdpdf": {
      "version": "1.7.3",
      "resolved": "https://registry.npmjs.org/mdpdf/-/mdpdf-1.7.3.tgz",
      "integrity": "sha512-yvLnXcg1j7JsaC1l1BNc7QUePOF5br8Oqi0lUu2NzysWbe2YKgSBWFi9V9/5X4rx2BjCHxD5+f5jLXkkN4t8qg==",
      "requires": {
        "bluebird": "^3.4.7",
        "cheerio": "^0.22.0",
        "file-url": "^2.0.2",
        "handlebars": "^4.0.6",
        "html-pdf": "^2.2.0",
        "loophole": "^1.1.0",
        "meow": "^3.7.0",
        "showdown": "^1.6.0",
        "showdown-emoji": "^1.0.3"
      }
    },

into that : git://github.com/bluehatbrit/mdpdf.git#puppeteer-upgrade

image Or the first one ?

DEYROS avatar Jun 24 '22 13:06 DEYROS

image image I should replace that :

"mdpdf": {
      "version": "1.7.3",
      "resolved": "https://registry.npmjs.org/mdpdf/-/mdpdf-1.7.3.tgz",
      "integrity": "sha512-yvLnXcg1j7JsaC1l1BNc7QUePOF5br8Oqi0lUu2NzysWbe2YKgSBWFi9V9/5X4rx2BjCHxD5+f5jLXkkN4t8qg==",
      "requires": {
        "bluebird": "^3.4.7",
        "cheerio": "^0.22.0",
        "file-url": "^2.0.2",
        "handlebars": "^4.0.6",
        "html-pdf": "^2.2.0",
        "loophole": "^1.1.0",
        "meow": "^3.7.0",
        "showdown": "^1.6.0",
        "showdown-emoji": "^1.0.3"
      }
    },

into that : git://github.com/bluehatbrit/mdpdf.git#puppeteer-upgrade

image Or the first one ?

package.json not package-lock you should never edit package-lock

nopeless avatar Jun 24 '22 13:06 nopeless

Oh my bad, So I should make something like that ? image And run npm install and re run my code ?

DEYROS avatar Jun 24 '22 13:06 DEYROS

Yep!

elliotblackburn avatar Jun 24 '22 13:06 elliotblackburn

I did it but now I encounter a timeout how can I change this one ? image I already did it but don't remember

 _LifecycleWatcher_createTimeoutPromise = async function _LifecycleWatcher_createTimeoutPromise() {
    if (!__classPrivateFieldGet(this, _LifecycleWatcher_timeout, "f")) {
        return new Promise(noop);
    }
    const errorMessage = 'Navigation timeout of ' + __classPrivateFieldGet(this, _LifecycleWatcher_timeout, "f") + ' ms exceeded';
    await new Promise(fulfill => {
        return (__classPrivateFieldSet(this, _LifecycleWatcher_maximumTimer, setTimeout(fulfill, __classPrivateFieldGet(this, _LifecycleWatcher_timeout, "f")), "f"));
    });
    return new Errors_js_1.TimeoutError(errorMessage);
},

DEYROS avatar Jun 24 '22 13:06 DEYROS

I did it but now I encounter a timeout how can I change this one ? image I already did it but don't remember

 _LifecycleWatcher_createTimeoutPromise = async function _LifecycleWatcher_createTimeoutPromise() {
    if (!__classPrivateFieldGet(this, _LifecycleWatcher_timeout, "f")) {
        return new Promise(noop);
    }
    const errorMessage = 'Navigation timeout of ' + __classPrivateFieldGet(this, _LifecycleWatcher_timeout, "f") + ' ms exceeded';
    await new Promise(fulfill => {
        return (__classPrivateFieldSet(this, _LifecycleWatcher_maximumTimer, setTimeout(fulfill, __classPrivateFieldGet(this, _LifecycleWatcher_timeout, "f")), "f"));
    });
    return new Errors_js_1.TimeoutError(errorMessage);
},

Can you make your .md file smaller? Just to see whether footer will work. After fixing that problem, you can start working on figuring out how to increase navigation timeout

nopeless avatar Jun 24 '22 13:06 nopeless

I make it smaller and : image image image It """""work"""" I don't really understand why there is not any css or even the image at the top

DEYROS avatar Jun 24 '22 13:06 DEYROS

So when I have this I can saw the number of pages : image But the css isn't used anymore And when I have this : image The css is used but I can't see the number of pages hmmm interesting

DEYROS avatar Jun 24 '22 13:06 DEYROS

I make it smaller and : image image image It """""work"""" I don't really understand why there is not any css or even the image at the top

Hey at least its working

nopeless avatar Jun 24 '22 14:06 nopeless

😂

DEYROS avatar Jun 24 '22 14:06 DEYROS

In the puppeteer update I just did a blind update from v2 to v15 so I've not actually checked much but that the tests run. It could be that they process css differently now. It was always a real ballache because we had to hand in the CSS basically 3 times when I first integrated it.

It might be a case of just checking the docs to see how to pass in css now. IIRC last time I figured it out with trial and error as it wasn't well documented so there's a good chance it's changed now.

elliotblackburn avatar Jun 24 '22 14:06 elliotblackburn

But actually the css is used but not completly as you can see the title are in red : image with the font "calibri" i just don't have the css on the footer and to the header

DEYROS avatar Jun 24 '22 14:06 DEYROS

Headers and footers don't use the main document css, we have the inject it for the body, header, and footer seperately. It sounds like between v2 and v15 something was changed with how puppeteer handles those.

elliotblackburn avatar Jun 24 '22 14:06 elliotblackburn

@BlueHatbRit with that being said, the puppeteer bump should be released as a major version

nopeless avatar Jun 25 '22 05:06 nopeless

I agree, I'll need to do some additional testing as well to ensure other scenarios still work.

I think it'd be wise to do the release after the final security upgrade as well. Meow requires the project to be using esmodules which has potential to slightly shift out API also. It's something I'm looking at but may take a bit. If it's going to take me longer than a week or so I may need to just do them separately though.

elliotblackburn avatar Jun 25 '22 07:06 elliotblackburn

3.0.1 is released now which fixes the numbering, will continue to look into the styling issue when time permits though.

elliotblackburn avatar Jun 29 '22 14:06 elliotblackburn