@neilkrichi/pdf-cli
Version:
A CLI tool for splitting and merging PDF files
92 lines (91 loc) • 4.74 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.splitPDF = splitPDF;
const pdf_lib_1 = require("pdf-lib");
const promises_1 = require("fs/promises");
const fs_1 = require("fs");
const path_1 = __importDefault(require("path"));
const chalk_1 = __importDefault(require("chalk"));
const utils_1 = require("./utils");
async function splitPDF(file, outputFolder = "output_pdfs", rangeString) {
try {
console.log(chalk_1.default.blue("🔄 Processing PDF..."));
// Parse range string if provided
let pageRange;
if (rangeString) {
const [start, end] = rangeString.split('-').map(Number);
pageRange = { start, end };
}
const normalizedFile = path_1.default.normalize(file);
const normalizedOutputFolder = path_1.default.normalize(outputFolder);
const baseFileName = path_1.default.basename(normalizedFile, '.pdf');
if (!(0, fs_1.existsSync)(normalizedOutputFolder)) {
console.log(chalk_1.default.yellow(`📁 Creating folder: ${normalizedOutputFolder}`));
await (0, promises_1.mkdir)(normalizedOutputFolder, { recursive: true });
}
const pdfBytes = await (0, promises_1.readFile)(normalizedFile);
const pdf = await pdf_lib_1.PDFDocument.load(pdfBytes);
// Validate page range
const totalPages = pdf.getPageCount();
let startPage = 1;
let endPage = totalPages;
if (pageRange) {
if (pageRange.start < 1 || pageRange.end > totalPages || pageRange.start > pageRange.end) {
throw new Error(`Invalid page range. Document has ${totalPages} pages. Requested range: ${pageRange.start}-${pageRange.end}`);
}
startPage = pageRange.start;
endPage = pageRange.end;
}
// Convert to 0-based index for internal use
const startIndex = startPage - 1;
const endIndex = endPage - 1;
if (pageRange) {
// Create a single PDF with the selected range
const outputPath = path_1.default.join(normalizedOutputFolder, `${baseFileName}-pages-${startPage}-to-${endPage}.pdf`);
if ((0, fs_1.existsSync)(outputPath)) {
const shouldContinue = await (0, utils_1.confirmOverwrite)(outputPath);
if (!shouldContinue) {
console.log(chalk_1.default.yellow("⚠️ Operation cancelled"));
process.exit(0);
}
}
const newPdf = await pdf_lib_1.PDFDocument.create();
const pageIndexes = Array.from({ length: endIndex - startIndex + 1 }, (_, i) => startIndex + i);
const copiedPages = await newPdf.copyPages(pdf, pageIndexes);
copiedPages.forEach(page => newPdf.addPage(page));
const newPdfBytes = await newPdf.save();
await (0, promises_1.writeFile)(outputPath, newPdfBytes);
console.log(chalk_1.default.green(`✅ Saved: ${outputPath}`));
console.log(chalk_1.default.green(`🎉 Extraction completed successfully! Pages ${startPage}-${endPage}`));
}
else {
// Split into individual pages
console.log(chalk_1.default.blue(`📄 Splitting into ${totalPages} individual pages...`));
for (let i = startIndex; i <= endIndex; i++) {
const pageNum = i + 1;
const outputPath = path_1.default.join(normalizedOutputFolder, `${baseFileName}-page-${pageNum}.pdf`);
if ((0, fs_1.existsSync)(outputPath)) {
const shouldContinue = await (0, utils_1.confirmOverwrite)(outputPath);
if (!shouldContinue) {
console.log(chalk_1.default.yellow(`⚠️ Skipping page ${pageNum}`));
continue;
}
}
const newPdf = await pdf_lib_1.PDFDocument.create();
const [copiedPage] = await newPdf.copyPages(pdf, [i]);
newPdf.addPage(copiedPage);
const newPdfBytes = await newPdf.save();
await (0, promises_1.writeFile)(outputPath, newPdfBytes);
console.log(chalk_1.default.green(`✅ Saved page ${pageNum}: ${outputPath}`));
}
console.log(chalk_1.default.green(`🎉 Split completed successfully! Created ${totalPages} files`));
}
}
catch (error) {
console.error(chalk_1.default.red("❌ Error processing PDF: "), error);
process.exit(1);
}
}