Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add hooks for mdpdf header/footer in atom config #163

Open
travs opened this issue Aug 20, 2017 · 8 comments
Open

Add hooks for mdpdf header/footer in atom config #163

travs opened this issue Aug 20, 2017 · 8 comments

Comments

@travs
Copy link
Owner

travs commented Aug 20, 2017

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

@BlueHatbRit
Copy link
Collaborator

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.

@travs
Copy link
Owner Author

travs commented Aug 27, 2017

@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 😄

@BlueHatbRit
Copy link
Collaborator

@travs that's fantastic, great job on the release. This will be a great way of giving mdpdf a hard run as well.

@darebrawley
Copy link

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.

@neo1949
Copy link

neo1949 commented May 13, 2020

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.

  1. Use grep -rn "page.pdf" to serach in markdown-pdf package to find where this method was called. We can find it was called in mdpdf/src/index.js.

  2. 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);
    })
  1. Use Ctrl+Shift+I to open atom developer tools, then use Ctrl+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.

@BlueHatbRit
Copy link
Collaborator

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.

@neo1949
Copy link

neo1949 commented Jul 1, 2020

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:

sample image

Hope this can help someone who is struggling with this problem.

@east-winds
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants