Skip to content

Commit aa20184

Browse files
committed
Merge branch 'master' of https://github.com/lucee/extension-pdf
2 parents cd39cd5 + eb445bc commit aa20184

6 files changed

Lines changed: 442 additions & 1 deletion

File tree

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,7 @@ va specific
88
target
99
target/*
1010
*.DS_Store
11-
/cache
11+
/cache
12+
/.claude
13+
/test-output
14+
/.claude

tests/DocumentHeaderFooter.cfc

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
component extends="org.lucee.cfml.test.LuceeTestCase" labels="pdf" {
2+
3+
function beforeAll() {
4+
variables.path = getDirectoryFromPath( getCurrentTemplatePath() ) & "DocumentHeaderFooter/";
5+
afterAll();
6+
7+
if ( !directoryExists( variables.path ) ) directoryCreate( variables.path );
8+
}
9+
10+
function run( testResults, testBox ) {
11+
describe( "cfdocument headers", function() {
12+
13+
it( title="document with header", body=function( currentSpec ) {
14+
document format="pdf" filename="#path#with_header.pdf" overwrite=true {
15+
documentItem type="header" {
16+
writeOutput( "<div style='text-align:center;'>Document Header</div>" );
17+
}
18+
writeOutput( "<h1>Content</h1><p>This document has a header.</p>" );
19+
}
20+
21+
expect( isPDFFile( "#path#with_header.pdf" ) ).toBeTrue();
22+
});
23+
24+
it( title="header appears on all pages", body=function( currentSpec ) {
25+
document format="pdf" filename="#path#header_multipage.pdf" overwrite=true {
26+
documentItem type="header" {
27+
writeOutput( "<div>Page Header</div>" );
28+
}
29+
writeOutput( "<h1>Page 1</h1>" );
30+
documentItem type="pagebreak";
31+
writeOutput( "<h1>Page 2</h1>" );
32+
documentItem type="pagebreak";
33+
writeOutput( "<h1>Page 3</h1>" );
34+
}
35+
36+
expect( isPDFFile( "#path#header_multipage.pdf" ) ).toBeTrue();
37+
pdf action="getInfo" source="#path#header_multipage.pdf" name="local.info";
38+
expect( info.totalPages ).toBe( 3 );
39+
});
40+
41+
});
42+
43+
describe( "cfdocument footers", function() {
44+
45+
it( title="document with footer", body=function( currentSpec ) {
46+
document format="pdf" filename="#path#with_footer.pdf" overwrite=true {
47+
documentItem type="footer" {
48+
writeOutput( "<div style='text-align:center;'>Document Footer</div>" );
49+
}
50+
writeOutput( "<h1>Content</h1><p>This document has a footer.</p>" );
51+
}
52+
53+
expect( isPDFFile( "#path#with_footer.pdf" ) ).toBeTrue();
54+
});
55+
56+
it( title="footer appears on all pages", body=function( currentSpec ) {
57+
document format="pdf" filename="#path#footer_multipage.pdf" overwrite=true {
58+
documentItem type="footer" {
59+
writeOutput( "<div>Page Footer</div>" );
60+
}
61+
writeOutput( "<h1>Page 1</h1>" );
62+
documentItem type="pagebreak";
63+
writeOutput( "<h1>Page 2</h1>" );
64+
}
65+
66+
expect( isPDFFile( "#path#footer_multipage.pdf" ) ).toBeTrue();
67+
pdf action="getInfo" source="#path#footer_multipage.pdf" name="local.info";
68+
expect( info.totalPages ).toBe( 2 );
69+
});
70+
71+
});
72+
73+
describe( "cfdocument header and footer combined", function() {
74+
75+
it( title="document with both header and footer", body=function( currentSpec ) {
76+
document format="pdf" filename="#path#header_footer.pdf" overwrite=true {
77+
documentItem type="header" {
78+
writeOutput( "<div style='border-bottom:1px solid black;'>Header Content</div>" );
79+
}
80+
documentItem type="footer" {
81+
writeOutput( "<div style='border-top:1px solid black;'>Footer Content</div>" );
82+
}
83+
writeOutput( "<h1>Main Content</h1><p>This document has both header and footer.</p>" );
84+
}
85+
86+
expect( isPDFFile( "#path#header_footer.pdf" ) ).toBeTrue();
87+
});
88+
89+
it( title="header and footer with page numbers", body=function( currentSpec ) {
90+
document format="pdf" filename="#path#page_numbers.pdf" overwrite=true {
91+
documentItem type="header" {
92+
writeOutput( "<div>Report Title</div>" );
93+
}
94+
documentItem type="footer" evalAtPrint=true {
95+
writeOutput( "<div style='text-align:center;'>Page ##cfdocument.currentpagenumber## of ##cfdocument.totalpagecount##</div>" );
96+
}
97+
writeOutput( "<h1>Page 1 Content</h1>" );
98+
documentItem type="pagebreak";
99+
writeOutput( "<h1>Page 2 Content</h1>" );
100+
documentItem type="pagebreak";
101+
writeOutput( "<h1>Page 3 Content</h1>" );
102+
}
103+
104+
expect( isPDFFile( "#path#page_numbers.pdf" ) ).toBeTrue();
105+
pdf action="getInfo" source="#path#page_numbers.pdf" name="local.info";
106+
expect( info.totalPages ).toBe( 3 );
107+
});
108+
109+
});
110+
}
111+
112+
function afterAll() {
113+
if ( directoryExists( variables.path ) ) directoryDelete( variables.path, true );
114+
}
115+
}

tests/DocumentPageSettings.cfc

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
component extends="org.lucee.cfml.test.LuceeTestCase" labels="pdf" {
2+
3+
function beforeAll() {
4+
variables.path = getDirectoryFromPath( getCurrentTemplatePath() ) & "DocumentPageSettings/";
5+
afterAll();
6+
7+
if ( !directoryExists( variables.path ) ) directoryCreate( variables.path );
8+
}
9+
10+
function run( testResults, testBox ) {
11+
describe( "cfdocument page types", function() {
12+
13+
it( title="create A4 PDF", body=function( currentSpec ) {
14+
document format="pdf" pagetype="A4" filename="#path#a4.pdf" overwrite=true {
15+
writeOutput( "<h1>A4 Document</h1>" );
16+
}
17+
expect( isPDFFile( "#path#a4.pdf" ) ).toBeTrue();
18+
});
19+
20+
it( title="create Letter PDF", body=function( currentSpec ) {
21+
document format="pdf" pagetype="letter" filename="#path#letter.pdf" overwrite=true {
22+
writeOutput( "<h1>Letter Document</h1>" );
23+
}
24+
expect( isPDFFile( "#path#letter.pdf" ) ).toBeTrue();
25+
});
26+
27+
it( title="create Legal PDF", body=function( currentSpec ) {
28+
document format="pdf" pagetype="legal" filename="#path#legal.pdf" overwrite=true {
29+
writeOutput( "<h1>Legal Document</h1>" );
30+
}
31+
expect( isPDFFile( "#path#legal.pdf" ) ).toBeTrue();
32+
});
33+
34+
it( title="create custom size PDF", body=function( currentSpec ) {
35+
document format="pdf" pagetype="custom" pagewidth="5" pageheight="7" filename="#path#custom.pdf" overwrite=true {
36+
writeOutput( "<h1>Custom Size Document</h1>" );
37+
}
38+
expect( isPDFFile( "#path#custom.pdf" ) ).toBeTrue();
39+
});
40+
41+
});
42+
43+
describe( "cfdocument orientation", function() {
44+
45+
it( title="create portrait PDF", body=function( currentSpec ) {
46+
document format="pdf" orientation="portrait" filename="#path#portrait.pdf" overwrite=true {
47+
writeOutput( "<h1>Portrait Document</h1>" );
48+
}
49+
expect( isPDFFile( "#path#portrait.pdf" ) ).toBeTrue();
50+
});
51+
52+
it( title="create landscape PDF", body=function( currentSpec ) {
53+
document format="pdf" orientation="landscape" filename="#path#landscape.pdf" overwrite=true {
54+
writeOutput( "<h1>Landscape Document</h1>" );
55+
}
56+
expect( isPDFFile( "#path#landscape.pdf" ) ).toBeTrue();
57+
});
58+
59+
});
60+
61+
describe( "cfdocument margins", function() {
62+
63+
it( title="create PDF with inch margins", body=function( currentSpec ) {
64+
document format="pdf" unit="in" margintop="1" marginbottom="1" marginleft="1" marginright="1" filename="#path#margins_inch.pdf" overwrite=true {
65+
writeOutput( "<h1>1 Inch Margins</h1>" );
66+
}
67+
expect( isPDFFile( "#path#margins_inch.pdf" ) ).toBeTrue();
68+
});
69+
70+
it( title="create PDF with cm margins", body=function( currentSpec ) {
71+
document format="pdf" unit="cm" margintop="2" marginbottom="2" marginleft="2" marginright="2" filename="#path#margins_cm.pdf" overwrite=true {
72+
writeOutput( "<h1>2cm Margins</h1>" );
73+
}
74+
expect( isPDFFile( "#path#margins_cm.pdf" ) ).toBeTrue();
75+
});
76+
77+
it( title="create PDF with zero margins", body=function( currentSpec ) {
78+
document format="pdf" margintop="0" marginbottom="0" marginleft="0" marginright="0" filename="#path#margins_zero.pdf" overwrite=true {
79+
writeOutput( "<h1>Zero Margins</h1>" );
80+
}
81+
expect( isPDFFile( "#path#margins_zero.pdf" ) ).toBeTrue();
82+
});
83+
84+
});
85+
86+
describe( "cfdocument combined settings", function() {
87+
88+
it( title="create A4 landscape with custom margins", body=function( currentSpec ) {
89+
document format="pdf" pagetype="A4" orientation="landscape" unit="cm" margintop="1.5" marginbottom="1.5" marginleft="2" marginright="2" filename="#path#combined.pdf" overwrite=true {
90+
writeOutput( "<h1>Combined Settings</h1><p>A4 Landscape with custom margins</p>" );
91+
}
92+
expect( isPDFFile( "#path#combined.pdf" ) ).toBeTrue();
93+
});
94+
95+
});
96+
}
97+
98+
function afterAll() {
99+
if ( directoryExists( variables.path ) ) directoryDelete( variables.path, true );
100+
}
101+
}

tests/DocumentSectionItem.cfc

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
component extends="org.lucee.cfml.test.LuceeTestCase" labels="pdf" {
2+
3+
function beforeAll() {
4+
variables.path = getDirectoryFromPath( getCurrentTemplatePath() ) & "DocumentSectionItem/";
5+
afterAll();
6+
7+
if ( !directoryExists( variables.path ) ) directoryCreate( variables.path );
8+
}
9+
10+
function run( testResults, testBox ) {
11+
describe( "cfdocumentitem", function() {
12+
13+
it( title="pagebreak creates multiple pages", body=function( currentSpec ) {
14+
document format="pdf" filename="#path#pagebreak.pdf" overwrite=true {
15+
writeOutput( "<h1>Page 1</h1>" );
16+
documentItem type="pagebreak";
17+
writeOutput( "<h1>Page 2</h1>" );
18+
documentItem type="pagebreak";
19+
writeOutput( "<h1>Page 3</h1>" );
20+
}
21+
22+
pdf action="getInfo" source="#path#pagebreak.pdf" name="local.info";
23+
expect( info.totalPages ).toBe( 3 );
24+
});
25+
26+
});
27+
28+
describe( "cfdocumentsection", function() {
29+
30+
it( title="section with different margins", body=function( currentSpec ) {
31+
document format="pdf" filename="#path#sections.pdf" overwrite=true {
32+
documentSection margintop="0.5" marginbottom="0.5" {
33+
writeOutput( "<h1>Section 1</h1><p>Small margins</p>" );
34+
}
35+
documentSection margintop="2" marginbottom="2" {
36+
writeOutput( "<h1>Section 2</h1><p>Large margins</p>" );
37+
}
38+
}
39+
40+
expect( isPDFFile( "#path#sections.pdf" ) ).toBeTrue();
41+
});
42+
43+
it( title="section with different page orientation", body=function( currentSpec ) {
44+
document format="pdf" filename="#path#section_orient.pdf" overwrite=true {
45+
documentSection orientation="portrait" {
46+
writeOutput( "<h1>Portrait Section</h1>" );
47+
}
48+
documentSection orientation="landscape" {
49+
writeOutput( "<h1>Landscape Section</h1>" );
50+
}
51+
}
52+
53+
expect( isPDFFile( "#path#section_orient.pdf" ) ).toBeTrue();
54+
pdf action="getInfo" source="#path#section_orient.pdf" name="local.info";
55+
expect( info.totalPages ).toBe( 2 );
56+
});
57+
58+
it( title="section with header and footer", body=function( currentSpec ) {
59+
document format="pdf" filename="#path#section_hf.pdf" overwrite=true {
60+
documentSection {
61+
documentItem type="header" {
62+
writeOutput( "<div>Section Header</div>" );
63+
}
64+
documentItem type="footer" {
65+
writeOutput( "<div>Section Footer</div>" );
66+
}
67+
writeOutput( "<h1>Content</h1><p>This section has its own header and footer.</p>" );
68+
}
69+
}
70+
71+
expect( isPDFFile( "#path#section_hf.pdf" ) ).toBeTrue();
72+
});
73+
74+
it( title="multiple sections with pagebreaks between", body=function( currentSpec ) {
75+
document format="pdf" filename="#path#multi_section.pdf" overwrite=true {
76+
documentSection {
77+
writeOutput( "<h1>Section 1 - Page 1</h1>" );
78+
documentItem type="pagebreak";
79+
writeOutput( "<h1>Section 1 - Page 2</h1>" );
80+
}
81+
documentSection {
82+
writeOutput( "<h1>Section 2 - Page 1</h1>" );
83+
}
84+
}
85+
86+
expect( isPDFFile( "#path#multi_section.pdf" ) ).toBeTrue();
87+
pdf action="getInfo" source="#path#multi_section.pdf" name="local.info";
88+
expect( info.totalPages ).toBe( 3 );
89+
});
90+
91+
});
92+
}
93+
94+
function afterAll() {
95+
if ( directoryExists( variables.path ) ) directoryDelete( variables.path, true );
96+
}
97+
}

tests/PDFDeletePages.cfc

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
component extends="org.lucee.cfml.test.LuceeTestCase" labels="pdf" {
2+
3+
function beforeAll() {
4+
variables.path = getDirectoryFromPath( getCurrentTemplatePath() ) & "PDFDeletePages/";
5+
afterAll();
6+
7+
if ( !directoryExists( variables.path ) ) directoryCreate( variables.path );
8+
9+
// Create a 3-page PDF
10+
document fileName="#path#source.pdf" overwrite=true {
11+
writeOutput( "<h1>Page 1</h1>" );
12+
documentItem type="pagebreak";
13+
writeOutput( "<h1>Page 2</h1>" );
14+
documentItem type="pagebreak";
15+
writeOutput( "<h1>Page 3</h1>" );
16+
}
17+
}
18+
19+
function run( testResults, testBox ) {
20+
describe( "cfpdf action=deletePages", function() {
21+
22+
it( title="delete single page from PDF", body=function( currentSpec ) {
23+
fileCopy( "#path#source.pdf", "#path#test1.pdf" );
24+
25+
pdf action="deletePages" source="#path#test1.pdf" pages="2";
26+
27+
pdf action="getInfo" source="#path#test1.pdf" name="local.info";
28+
expect( info.totalPages ).toBe( 2 );
29+
});
30+
31+
it( title="delete multiple pages from PDF", body=function( currentSpec ) {
32+
fileCopy( "#path#source.pdf", "#path#test2.pdf" );
33+
34+
pdf action="deletePages" source="#path#test2.pdf" pages="1,3";
35+
36+
pdf action="getInfo" source="#path#test2.pdf" name="local.info";
37+
expect( info.totalPages ).toBe( 1 );
38+
});
39+
40+
it( title="delete page range from PDF", body=function( currentSpec ) {
41+
fileCopy( "#path#source.pdf", "#path#test3.pdf" );
42+
43+
pdf action="deletePages" source="#path#test3.pdf" pages="1-2";
44+
45+
pdf action="getInfo" source="#path#test3.pdf" name="local.info";
46+
expect( info.totalPages ).toBe( 1 );
47+
});
48+
49+
it( title="delete pages with destination attribute", body=function( currentSpec ) {
50+
pdf action="deletePages" source="#path#source.pdf" pages="1" destination="#path#dest.pdf" overwrite=true;
51+
52+
expect( isPDFFile( "#path#dest.pdf" ) ).toBeTrue();
53+
pdf action="getInfo" source="#path#dest.pdf" name="local.info";
54+
expect( info.totalPages ).toBe( 2 );
55+
// Original should be unchanged
56+
pdf action="getInfo" source="#path#source.pdf" name="local.origInfo";
57+
expect( origInfo.totalPages ).toBe( 3 );
58+
});
59+
60+
it( title="delete pages with name attribute", body=function( currentSpec ) {
61+
pdf action="deletePages" source="#path#source.pdf" pages="1" name="local.result";
62+
63+
expect( isPDFObject( result ) ).toBeTrue();
64+
});
65+
66+
});
67+
}
68+
69+
function afterAll() {
70+
if ( directoryExists( variables.path ) ) directoryDelete( variables.path, true );
71+
}
72+
}

0 commit comments

Comments
 (0)