markdown-pdf
markdown-pdf copied to clipboard
Add hooks for mdpdf header/footer in atom config
I was thinking of adding these hooks, but what is the exact shape of the header/footer config? Without looking at the source, it appears to be something like this:
{
pdf:
header: {
height: int
}
}
Where do I add the content?
cc: @BlueHatbRit
It is literally just a height parameter as you've got there. However you might need to sit back and figure out how you want this feature to work. The general pattern in mdpdf (cli) is to create a separate HTML file for the header and one for the footer (depending on which is applicable). This is then fed in using a command line argument. I guess you'd probably handle it in a similar way to how you're handling stylesheets (if you're allowing users to specify custom ones that is).
Checkout the mdpdf examples API folder for a more detailed example of how headers and footers work.
@BlueHatbRit Ok excellent; going to have a look into this. Just wanted to ping and let you know I just made the release. Looks so far like it should work 😄
@travs that's fantastic, great job on the release. This will be a great way of giving mdpdf a hard run as well.
Hi , I wanted to follow up on this issue and to ask whether this header/footer functionality has been added? I am especially interested in being able to add page numbers in a footer and haven't been able to find any documentation about whether this is possible with markdown-pdf. Any assistance would be greatly appreciated.
Hi, I cannot find a way to add header and footer in generated pdf.
I find you have ever commented here, so I searched the puppeteer issues.
According to Possibility for page numbers in PDF? #373 and How to print pages/ page numbers/pagination in pdf puppeteer? #5345, the keypoint to add header/footer in generated pdf is using snippet like below:
await page.pdf({
path: 'hacks.pdf',
format: 'A4',
displayHeaderFooter: true,
headerTemplate: `<div class='date'></div><div class='title'></div>`
footerTemplate: `<div><div class='pageNumber'></div> <div>/</div><div class='totalPages'></div></div>`
});
I tried to modify the ~/.atom/packages/markdown-pdf/node_modules/puppeteer/lib/Page.js
like this:
async pdf(options = {}) {
const {
......
displayHeaderFooter = true,
headerTemplate = `<div class='date'></div><div class='title'></div>`,
footerTemplate = `<div><div class='pageNumber'></div> <div>/</div><div class='totalPages'></div></div>`,
......
}
}
But it does not work, no footer or header was generated in generated pdf.
Why this does not work? Maybe the problem was caused by the mdpdf. So I made some debugging.
-
Use
grep -rn "page.pdf"
to serach inmarkdown-pdf
package to find where this method was called. We can find it was called in mdpdf/src/index.js. -
Add some logs in
mdpdf/src/index.js
:
.then(() => {
const puppetOptions = puppeteerHelper.getOptions(options);
console.log("[mdpdf] displayHeaderFooter: " + puppetOptions.displayHeaderFooter);
console.log("[mdpdf] headerTemplate:%s footerTemplate:%s", puppetOptions.headerTemplate, puppetOptions.footerTemplate);
return page.pdf(puppetOptions);
})
- Use
Ctrl+Shift+I
to open atom developer tools, then useCtrl+Alt+E
to export markdown to pdf, you will the logs:
~/.atom/packages/markdown-pdf/node_modules/mdpdf/src/index.js:192 [mdpdf] displayHeaderFooter: false
~/.atom/packages/markdown-pdf/node_modules/mdpdf/src/index.js:193 [mdpdf] headerTemplate: footerTemplate:
The reason was clear now, the mdpdf did not use corresponding params when generating pdf.
Now, the problem becomes how to add footer and header template in mdpdf. Since I know barely about js, I hope you could give me some advice on how to accomplish that.
Hi @neo1949, i'm the creator of mdpdf 😄 if you checkout the mdpdf docs they let you pass in a file path for the header / footer to be rendered. The problem is that the styling from the main document css isn't applied due to Puppeteer 😢 that means the header and footer end up in times new roman sort of style.
That's probably the more important thing to fix, we can then modify mdpdf to take in a string for the header and footer if that makes things easier for markdown-pdf.
Hi @BlueHatbRit, sorry for the late reply. I modified the source of the below file and finally got the header and footer.
~/.atom/packages/markdown-pdf/node_modules/mdpdf/src/puppeteer-helper.js
The change was like this:
function getOptions(options) {
let displayHeaderFooter = true;
if (options.header || options.footer) {
displayHeaderFooter = true;
}
let margin = {};
if (options.pdf.border) {
margin.top = options.pdf.border.top || undefined;
margin.right = options.pdf.border.right || undefined;
margin.bottom = options.pdf.border.bottom || undefined;
margin.left = options.pdf.border.left || undefined;
}
let date = (new Date()).Format("yyyy");
let myHeaderTemplate = `<div style="font:6px Monaco; margin-left:68%;"><div style="display:inline;">© ${date} neo1949. All Rights Reserved</div></div>`;
let myFooterTemplate = `
<div style="width:83%;"></div>
<div style="font:8px Monaco;">
<div style="display:inline;">Page </div><div style="display:inline;" class="pageNumber"></div><div style="display:inline;">/</div><div style="display:inline;" class="totalPages"></div>
</div>`;
return {
path: options.destination,
displayHeaderFooter: false,
printBackground: true,
format: options.pdf.format,
margin,
displayHeaderFooter,
headerTemplate: options.header || myHeaderTemplate,
footerTemplate: options.footer || myFooterTemplate,
landscape: (options.pdf.orientation && options.pdf.orientation == 'landscape')
}
}
module.exports = {
getOptions,
};
Date.prototype.Format = function (fmt) {
var o = {
"y+": this.getFullYear(),
"M+": this.getMonth() + 1, // 月份
"d+": this.getDate(), // 日
"h+": this.getHours(), // 小时
"m+": this.getMinutes(), // 分
"s+": this.getSeconds(), // 秒
"q+": Math.floor((this.getMonth() + 3) / 3), // 季度
"S+": this.getMilliseconds() // 毫秒
};
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)){
if(k == "y+"){
fmt = fmt.replace(RegExp.$1, ("" + o[k]).substr(4 - RegExp.$1.length));
}
else if(k=="S+"){
var lens = RegExp.$1.length;
lens = lens==1?3:lens;
fmt = fmt.replace(RegExp.$1, ("00" + o[k]).substr(("" + o[k]).length - 1,lens));
}
else{
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
}
return fmt;
}
The converted pdf was like this:
Hope this can help someone who is struggling with this problem.
Thanks @neo1949 for providing the code to add a header/footer!
Currently, the header/footer is hard-coded via:
let displayHeaderFooter = true;
I was wondering how to pass this through the .md file, it looks like via options.header
and options.footer
. Is this in the YAML? It would be helpful to have the option to turn on and off the footer without having to edit puppeteer-helper.js
.