Skip to content

Commit 5485abd

Browse files
committed
Merge pull request #105 from marcbachmann/dynamic-header-and-footers
Support dynamic headers and footers
2 parents d25f2d1 + 6bb48cf commit 5485abd

File tree

8 files changed

+337
-42
lines changed

8 files changed

+337
-42
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
*.pdf
22
!example/businesscard.pdf
3+
node_modules

lib/index.js

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/pdf.js

Lines changed: 10 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/scripts/pdf_a4_portrait.js

Lines changed: 59 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"tape": "^3.4.0"
2525
},
2626
"optionalDependencies": {
27-
"phantomjs": "^1.9.16"
27+
"phantomjs": "^1.9.19"
2828
},
2929
"repository": {
3030
"type": "git",

src/scripts/pdf_a4_portrait.coffee

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,40 @@ setTimeout ->
5454
# ------------------------------
5555
getContent = ->
5656
page.evaluate ->
57+
getElements = (doc, wildcard) ->
58+
wildcardMatcher = new RegExp("#{wildcard}(.*)")
59+
hasElements = false
60+
elements = {}
61+
$elements = document.querySelectorAll("[id*='#{wildcard}']")
62+
for $elem in $elements
63+
if match = $elem.attributes.id.value.match(wildcardMatcher)
64+
hasElements = true
65+
i = match[1]
66+
elements[i] = $elem.outerHTML
67+
68+
$elem.parentNode.removeChild($elem)
69+
70+
if hasElements
71+
return elements
72+
73+
getElement = (doc, id) ->
74+
if $elem = doc.getElementById(id)
75+
html = $elem.outerHTML
76+
$elem.parentNode.removeChild($elem)
77+
return html
78+
5779
styles = document.querySelectorAll('link,style')
5880
styles = Array::reduce.call(styles, ((string, node) -> string+node.outerHTML),'')
59-
if $header = document.getElementById('pageHeader')
60-
header = $header.outerHTML
61-
$header.parentNode.removeChild($header)
6281

63-
if $footer = document.getElementById('pageFooter')
64-
footer = $footer.outerHTML
65-
$footer.parentNode.removeChild($footer)
82+
# Wildcard headers e.g. <div id="pageHeader-first"> or <div id="pageHeader-0">
83+
header = getElements(document, 'pageHeader-')
84+
footer = getElements(document, 'pageFooter-')
85+
86+
# Default header and footer e.g. <div id="pageHeader">
87+
h = getElement(document, 'pageHeader')
88+
f = getElement(document, 'pageFooter')
89+
(header ?= {}).default = h if h
90+
(footer ?= {}).default = f if f
6691

6792
if $body = document.getElementById('pageContent')
6893
body = $body.outerHTML
@@ -89,12 +114,18 @@ createPaper = (options) ->
89114

90115
# Creates page section
91116
# --------------------
92-
createSection = (content, styles, options) ->
93-
height: options?.height
117+
createSection = (section, content, options) ->
118+
c = content[section] || {}
119+
o = options[section] || {}
120+
121+
height: o.height
94122
contents: phantom.callback (pageNum, numPages) ->
95-
(options?.contents || content || '')
123+
html = c[pageNum]
124+
html ?= c['first'] if pageNum == 1
125+
html ?= c['last'] if pageNum == numPages
126+
(html || c.default || o.contents || '')
96127
.replace('{{page}}', pageNum)
97-
.replace('{{pages}}', numPages)+styles
128+
.replace('{{pages}}', numPages) + content.styles
98129

99130

100131
# Creates paper with generated footer & header
@@ -104,8 +135,7 @@ generatePaper = (content, options) ->
104135

105136
for section in ['header', 'footer']
106137
if options[section] || content[section]
107-
paper[section] =
108-
createSection(content[section], content.styles, options[section])
138+
paper[section] = createSection(section, content, options)
109139

110140
paper.header?.height ?= '46mm'
111141
paper.footer?.height ?= '28mm'

test/index.coffee

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,17 @@ test 'allows custom page and footer options', (st) ->
117117
st.assert(fs.existsSync(pdf.filename), 'Saves the pdf with a custom page size and footer')
118118

119119

120+
test 'allows different header and footer for first page', (st) ->
121+
st.plan(3)
122+
123+
enrichedHtml = fs.readFileSync(path.join(__dirname, 'multiple-pages.html'), 'utf8')
124+
filename = path.join(__dirname, 'multiple-pages.pdf')
125+
pdf.create(enrichedHtml, quality: 100).toFile filename, (error, pdf) ->
126+
st.error(error)
127+
st.assert(pdf.filename == filename, 'Returns the filename from the phantom script')
128+
st.assert(fs.existsSync(pdf.filename), 'Saves the pdf with a custom page size and footer')
129+
130+
120131
test 'load external css', (st) ->
121132
st.plan(3)
122133

0 commit comments

Comments
 (0)