From 544a080db4067ce7474449b9f5a3b80983189bd1 Mon Sep 17 00:00:00 2001 From: Saud Fatayerji Date: Fri, 17 Nov 2023 00:32:09 +0300 Subject: [PATCH] Made sort and extract pages functions conform to the new design pattern. Standardised naming of a few variables --- README.md | 4 +- client-ionic/src/utils/pdf-operations.ts | 4 +- client-vanilla/public/exampleWorkflows.js | 2 +- client-vanilla/public/functions.js | 8 +- .../src/functions/common/getPagesByIndex.ts | 21 ++ .../functions/common/pageIndexesSorting.ts | 121 +++++++++ .../src/functions/common/pageIndexesUtils.ts | 84 ++++++ .../src/functions/extractPages.ts | 20 ++ .../src/functions/removeBlankPages.ts | 18 ++ .../src/functions/sortPagesWithPreset.ts | 22 ++ shared-operations/src/functions/splitOn.ts | 6 +- shared-operations/src/functions/splitPDF.ts | 6 +- .../src/functions/subDocumentFunctions.ts | 255 ------------------ shared-operations/src/index.ts | 22 +- .../src/workflow/traverseOperations.ts | 4 +- 15 files changed, 312 insertions(+), 285 deletions(-) create mode 100644 shared-operations/src/functions/common/getPagesByIndex.ts create mode 100644 shared-operations/src/functions/common/pageIndexesSorting.ts create mode 100644 shared-operations/src/functions/common/pageIndexesUtils.ts create mode 100644 shared-operations/src/functions/extractPages.ts create mode 100644 shared-operations/src/functions/removeBlankPages.ts create mode 100644 shared-operations/src/functions/sortPagesWithPreset.ts delete mode 100644 shared-operations/src/functions/subDocumentFunctions.ts diff --git a/README.md b/README.md index fa5714d7..869fa0a6 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ To create your own, you have to understand a few key features first. You can als { "type": "extract", "values": { - "pagesToExtractArray": [0, 2] + "pageIndexes": [0, 2] }, "operations": [] } @@ -46,7 +46,7 @@ You can also nest workflows like this: { "type": "extract", "values": { - "pagesToExtractArray": [0, 2] + "pageIndexes": [0, 2] }, "operations": [ { diff --git a/client-ionic/src/utils/pdf-operations.ts b/client-ionic/src/utils/pdf-operations.ts index 0751d88a..560819b0 100644 --- a/client-ionic/src/utils/pdf-operations.ts +++ b/client-ionic/src/utils/pdf-operations.ts @@ -13,8 +13,8 @@ export async function editMetadata(snapshot: string | Uint8Array | ArrayBuffer, return dependantEditMetadata(snapshot, metadata); } -export async function extractPages(snapshot: string | Uint8Array | ArrayBuffer, pagesToExtractArray: number[]) { - return dependantExtractPages(snapshot, pagesToExtractArray); +export async function extractPages(snapshot: string | Uint8Array | ArrayBuffer, pageIndexes: number[]) { + return dependantExtractPages(snapshot, pageIndexes); } export async function mergePDFs(snapshots: (string | Uint8Array | ArrayBuffer)[]) { diff --git a/client-vanilla/public/exampleWorkflows.js b/client-vanilla/public/exampleWorkflows.js index 15cbefc1..f7dc33e0 100644 --- a/client-vanilla/public/exampleWorkflows.js +++ b/client-vanilla/public/exampleWorkflows.js @@ -90,7 +90,7 @@ export const extractOnly = { operations: [ { type: "extract", - values: { "pagesToExtractArray": [0, 2] }, + values: { "pageIndexes": [0, 2] }, operations: [] } ] diff --git a/client-vanilla/public/functions.js b/client-vanilla/public/functions.js index be7bf914..eb80f9c3 100644 --- a/client-vanilla/public/functions.js +++ b/client-vanilla/public/functions.js @@ -20,8 +20,8 @@ import { splitOn as dependantSplitOn } from "./functions/splitOn.js"; // TODO: Dynamic loading & undloading of libraries. -export async function extractPages(snapshot, pagesToExtractArray) { - return dependantExtractPages(snapshot, pagesToExtractArray, PDFLib); +export async function extractPages(snapshot, pageIndexes) { + return dependantExtractPages(snapshot, pageIndexes, PDFLib); } export async function impose(snapshot, nup, format) { @@ -52,8 +52,8 @@ export async function editMetadata(snapshot, metadata) { return dependantEditMetadata(snapshot, metadata, PDFLib); } -export async function sortPagesWithPreset(snapshot, operation, fancyPageSelector) { - return dependantSortPagesWithPreset(snapshot, operation, fancyPageSelector, PDFLib); +export async function sortPagesWithPreset(snapshot, operation) { + return dependantSortPagesWithPreset(snapshot, operation, PDFLib); } export async function removeBlankPages(snapshot, whiteThreashold) { diff --git a/shared-operations/src/functions/common/getPagesByIndex.ts b/shared-operations/src/functions/common/getPagesByIndex.ts new file mode 100644 index 00000000..d7498d8f --- /dev/null +++ b/shared-operations/src/functions/common/getPagesByIndex.ts @@ -0,0 +1,21 @@ + +import { PdfFile, RepresentationType } from '../../wrappers/PdfFile.js'; +import { PDFDocument } from 'pdf-lib'; + +export async function getPages(file: PdfFile, pageIndexes: number[]): Promise { + const pdfLibDocument = await file.pdfLibDocument; + const subDocument = await PDFDocument.create(); + + // Check that array max number is not larger pdf pages number + if(Math.max(...pageIndexes) >= pdfLibDocument.getPageCount()) { + throw new Error(`The PDF document only has ${pdfLibDocument.getPageCount()} pages and you tried to extract page ${Math.max(...pageIndexes)}`); + } + + const copiedPages = await subDocument.copyPages(pdfLibDocument, pageIndexes); + + for (let i = 0; i < copiedPages.length; i++) { + subDocument.addPage(copiedPages[i]); + } + + return new PdfFile(file.originalFilename, subDocument, RepresentationType.PDFLibDocument, file.filename); +} diff --git a/shared-operations/src/functions/common/pageIndexesSorting.ts b/shared-operations/src/functions/common/pageIndexesSorting.ts new file mode 100644 index 00000000..2ef73a93 --- /dev/null +++ b/shared-operations/src/functions/common/pageIndexesSorting.ts @@ -0,0 +1,121 @@ + +/** + * @param pages A list of page indexes, or the number of total pages in the document (which will be converted into a list of page indexes). + * @returns A reversed list of page indexes. + */ +function reverseSort(pages: number|number[]): number[] { + const indexes = Array.isArray(pages) ? pages : [...Array(pages).keys()]; + return indexes.reverse(); +} + +/** + * Sorts page indexes as if all fronts were scanned then all backs in reverse (1, n, 2, n-1, ...). + * @param pages A list of page indexes, or the number of total pages in the document (which will be converted into a list of page indexes). + * @returns A duplex-sorted list of page indexes. + */ +function duplexSort(pages: number|number[]): number[] { + const indexes = Array.isArray(pages) ? pages : [...Array(pages).keys()]; + + // Translated to JS from the original Java function + const newPageOrder: number[] = []; + const half = Math.floor((indexes.length + 1) / 2); // This ensures proper behavior with odd numbers of pages + + for (let i = 1; i <= half; i++) { + newPageOrder.push(indexes[i - 1]); + if (i <= indexes.length - half) { + // Avoid going out of bounds + newPageOrder.push(indexes[indexes.length - i]); + } + } + + return newPageOrder; +} + +/** + * Arranges pages for booklet printing (last, first, second, second last, ...). + * @param pages A list of page indexes, or the number of total pages in the document (which will be converted into a list of page indexes). + * @returns A booklet-sorted list of page indexes. + */ +function bookletSort(totalPages: number): number[] { + const newPageOrder: number[] = []; + for (let i = 0; i < totalPages / 2; i++) { + newPageOrder.push(i); + newPageOrder.push(totalPages - i - 1); + } + return newPageOrder; +} + +/** + * TODO: find out what this does + * @param pages + * @returns + */ +function sideStitchBooklet(totalPages: number): number[] { + const newPageOrder: number[] = []; + for (let i = 0; i < (totalPages + 3) / 4; i++) { + const begin = i * 4; + newPageOrder.push(Math.min(begin + 3, totalPages - 1)); + newPageOrder.push(Math.min(begin, totalPages - 1)); + newPageOrder.push(Math.min(begin + 1, totalPages - 1)); + newPageOrder.push(Math.min(begin + 2, totalPages - 1)); + } + return newPageOrder; +} + +/** + * Splits and arranges pages into odd and even numbered pages. + * @param pages A list of page indexes, or the number of total pages in the document (which will be converted into a list of page indexes). + * @returns An odd-even split list of page indexes. + */ +function oddEvenSplit(totalPages: number): number[] { + const newPageOrder: number[] = []; + for (let i = 1; i <= totalPages; i += 2) { + newPageOrder.push(i - 1); + } + for (let i = 2; i <= totalPages; i += 2) { + newPageOrder.push(i - 1); + } + return newPageOrder; +} + +/** + * Removes the first page from the list of index selections. + * @param pages A list of page indexes, or the number of total pages in the document (which will be converted into a list of page indexes). + * @returns The list of page indexes, without the first page. + */ +function removeFirst(totalPages: number): number[] { + return [...Array(totalPages-1).keys()].map(i => i+1); +} + +/** + * Removes the last page from the list of index selections. + * @param pages A list of page indexes, or the number of total pages in the document (which will be converted into a list of page indexes). + * @returns The list of page indexes, without the last page. + */ +function removeLast(totalPages: number): number[] { + return [...Array(totalPages-1).keys()]; +} + +/** + * Removes the first and last pages from the list of index selections. + * @param pages A list of page indexes, or the number of total pages in the document (which will be converted into a list of page indexes). + * @returns The list of page indexes, without the first and last pages. + */ +function removeFirstAndLast(totalPages: number): number[] { + return [...Array(totalPages-2).keys()].map(i => i+1); +} + +export type SortFunction = (totalPages: number) => number[]; +type Sorts = { + [key: string]: SortFunction; +}; +export const sorts: Sorts = Object.freeze({ + "REVERSE_ORDER": reverseSort, + "DUPLEX_SORT": duplexSort, + "BOOKLET_SORT": bookletSort, + "SIDE_STITCH_BOOKLET_SORT": sideStitchBooklet, + "ODD_EVEN_SPLIT": oddEvenSplit, + "REMOVE_FIRST": removeFirst, + "REMOVE_LAST": removeLast, + "REMOVE_FIRST_AND_LAST": removeFirstAndLast, +}); diff --git a/shared-operations/src/functions/common/pageIndexesUtils.ts b/shared-operations/src/functions/common/pageIndexesUtils.ts new file mode 100644 index 00000000..6a60f850 --- /dev/null +++ b/shared-operations/src/functions/common/pageIndexesUtils.ts @@ -0,0 +1,84 @@ + +/** + * @param selection An array of page indexes already selected. + * @param pages A list of page indexes, or the number of total pages in the document (which will be converted into a list of page indexes). + * @returns An inverted selection array of page indexes. + */ +function invertSelection(selection: number[], pages: number|number[]): number[] { + const indexes = Array.isArray(pages) ? pages : [...Array(pages).keys()]; + const pageIndexesCopy = [...indexes]; + return pageIndexesCopy.filter(x => !selection.includes(x)); +} + +/** + * Parse the page selector string used in the 'PDF Page Organizer' + * @param specification + * @param totalPages + * @returns + */ +function parsePageIndexSpecification(specification: string, totalPages: number): number[] { + // Translated to JS from the original Java function + const pageOrderArr = specification.split(",") + const newPageOrder: number[] = []; + + // loop through the page order array + pageOrderArr.forEach(element => { + if (element.toLocaleLowerCase() === "all") { + for (var i = 0; i < totalPages; i++) { + newPageOrder.push(i); + } + // As all pages are already added, no need to check further + return; + } + else if (element.match("\\d*n\\+?-?\\d*|\\d*\\+?n")) { + // Handle page order as a function + var coefficient = 0; + var constant = 0; + var coefficientExists = false; + var constantExists = false; + + if (element.includes("n")) { + var parts = element.split("n"); + if (!parts[0]) { + coefficient = parseInt(parts[0]); + coefficientExists = true; + } + if (parts.length > 1 && parts[1]) { + constant = parseInt(parts[1]); + constantExists = true; + } + } else if (element.includes("+")) { + constant = parseInt(element.replace("+", "")); + constantExists = true; + } + + for (var i = 1; i <= totalPages; i++) { + var pageNum = coefficientExists ? coefficient * i : i; + pageNum += constantExists ? constant : 0; + + if (pageNum <= totalPages && pageNum > 0) { + newPageOrder.push(pageNum - 1); + } + } + } else if (element.includes("-")) { + // split the range into start and end page + const range = element.split("-"); + const start = parseInt(range[0]); + var end = parseInt(range[1]); + // check if the end page is greater than total pages + if (end > totalPages) { + end = totalPages; + } + // loop through the range of pages + for (var j = start; j <= end; j++) { + // print the current index + newPageOrder.push(j - 1); + } + } else { + // if the element is a single page + newPageOrder.push(parseInt(element) - 1); + } + }); + + return newPageOrder; +} diff --git a/shared-operations/src/functions/extractPages.ts b/shared-operations/src/functions/extractPages.ts new file mode 100644 index 00000000..eeeadbbb --- /dev/null +++ b/shared-operations/src/functions/extractPages.ts @@ -0,0 +1,20 @@ + +import { PdfFile } from '../wrappers/PdfFile.js'; +import { getPages } from './common/getPagesByIndex.js'; + +export type ExtractPagesParamsType = { + file: PdfFile; + pageIndexes: string | number[]; +} +export async function extractPages(params: ExtractPagesParamsType) { + const { file, pageIndexes } = params; + const pdfLibDocument = await file.pdfLibDocument; + + var indexes = pageIndexes; + + if (!Array.isArray(indexes)) { + indexes = parsePageIndexSpecification(indexes, pdfLibDocument.getPageCount()); + } + + return getPages(file, indexes); +} diff --git a/shared-operations/src/functions/removeBlankPages.ts b/shared-operations/src/functions/removeBlankPages.ts new file mode 100644 index 00000000..d8242769 --- /dev/null +++ b/shared-operations/src/functions/removeBlankPages.ts @@ -0,0 +1,18 @@ + +import { PdfFile } from '../wrappers/PdfFile.js'; +import { detectEmptyPages } from './common/detectEmptyPages.js'; +import { getPages } from './common/getPagesByIndex.js'; + +export type RemoveBlankPagesParamsType = { + file: PdfFile; + whiteThreashold: number; +} +export async function removeBlankPages(params: RemoveBlankPagesParamsType) { + const { file, whiteThreashold } = params; + const pageCount = await file.pdfLibDocument; + + const emptyPages = await detectEmptyPages(file, whiteThreashold); + console.debug("Empty Pages: ", emptyPages); + const pagesToKeep = invertSelection(emptyPages, pageCount.getPageCount()) + return getPages(file, pagesToKeep); +} \ No newline at end of file diff --git a/shared-operations/src/functions/sortPagesWithPreset.ts b/shared-operations/src/functions/sortPagesWithPreset.ts new file mode 100644 index 00000000..d32ac943 --- /dev/null +++ b/shared-operations/src/functions/sortPagesWithPreset.ts @@ -0,0 +1,22 @@ + +import { PdfFile } from '../wrappers/PdfFile.js'; +import { sorts } from './common/pageIndexesSorting.js'; +import { getPages } from './common/getPagesByIndex.js'; + +export type SortPagesWithPresetParamsType = { + file: PdfFile; + sortPreset: string; +} +export async function sortPagesWithPreset(params: SortPagesWithPresetParamsType) { + const { file, sortPreset } = params; + const pdfLibDocument = await file.pdfLibDocument; + + if (!(sortPreset in sorts)) { + throw new Error("Supplied parameters not supported"); + } + + const sortFunction = sorts[sortPreset]; + const pageCount = pdfLibDocument.getPageCount(); + const sortIndexes = sortFunction(pageCount); + return getPages(file, sortIndexes); +} diff --git a/shared-operations/src/functions/splitOn.ts b/shared-operations/src/functions/splitOn.ts index e300911f..5f79c09d 100644 --- a/shared-operations/src/functions/splitOn.ts +++ b/shared-operations/src/functions/splitOn.ts @@ -3,7 +3,7 @@ import jsQR from "jsqr"; import { detectEmptyPages } from "./common/detectEmptyPages.js"; import { getImagesOnPage } from "./common/getImagesOnPage.js"; -import { selectPages } from "./subDocumentFunctions"; +import { getPages } from "./common/getPagesByIndex.js"; import { PdfFile } from '../wrappers/PdfFile.js'; export type SplitOnParamsType = { @@ -52,7 +52,7 @@ export async function splitOn(params: SplitOnParamsType) { console.log(i); if(i == splitAfter) { if(pagesArray.length > 0) { - subDocuments.push(await selectPages({file, pagesToExtractArray:pagesArray})); + subDocuments.push(await getPages(file, pagesArray)); pagesArray = []; } splitAfter = splitAtPages.shift(); @@ -63,7 +63,7 @@ export async function splitOn(params: SplitOnParamsType) { } } if(pagesArray.length > 0) { - subDocuments.push(await selectPages({file, pagesToExtractArray:pagesArray})); + subDocuments.push(await getPages(file, pagesArray)); } pagesArray = []; diff --git a/shared-operations/src/functions/splitPDF.ts b/shared-operations/src/functions/splitPDF.ts index d24cdf37..d5dfe948 100644 --- a/shared-operations/src/functions/splitPDF.ts +++ b/shared-operations/src/functions/splitPDF.ts @@ -1,5 +1,5 @@ -import { selectPages } from "./subDocumentFunctions"; +import { getPages } from "./common/getPagesByIndex"; import { PdfFile } from '../wrappers/PdfFile'; export type SplitPdfParamsType = { @@ -20,13 +20,13 @@ export async function splitPDF(params: SplitPdfParamsType): Promise { for (let i = 0; i < numberOfPages; i++) { if(splitAfter && i > splitAfter && pagesArray.length > 0) { - subDocuments.push(await selectPages({file, pagesToExtractArray:pagesArray})); + subDocuments.push(await getPages(file, pagesArray)); splitAfter = splitAfterPageArray.shift(); pagesArray = []; } pagesArray.push(i); } - subDocuments.push(await selectPages({file, pagesToExtractArray:pagesArray})); + subDocuments.push(await getPages(file, pagesArray)); pagesArray = []; return subDocuments; diff --git a/shared-operations/src/functions/subDocumentFunctions.ts b/shared-operations/src/functions/subDocumentFunctions.ts deleted file mode 100644 index d9292081..00000000 --- a/shared-operations/src/functions/subDocumentFunctions.ts +++ /dev/null @@ -1,255 +0,0 @@ - -import { PDFDocument } from 'pdf-lib'; -import { PdfFile, RepresentationType } from '../wrappers/PdfFile.js'; -import { detectEmptyPages } from "./common/detectEmptyPages.js"; - - -export type SortPagesWithPresetParamsType = { - file: PdfFile; - sortPreset: string; - fancyPageSelector: string; -} -export async function sortPagesWithPreset(params: SortPagesWithPresetParamsType) { - const { file, sortPreset } = params; - - if (sortPreset === "CUSTOM_PAGE_ORDER") { - return rearrangePages(params); // fancyPageSelector passed down with params - } - - const sortFunction = sorts[sortPreset]; - if (!sortFunction) { - throw new Error("Operation not supported"); - } - - const pdfLibDocument = await file.pdfLibDocument; - - const pageCount = pdfLibDocument.getPageCount(); - const sortIndecies = sortFunction(pageCount); - return selectPages({file: file, pagesToExtractArray: sortIndecies}); -} - -export type RearrangePagesParamsType = { - file: PdfFile; - sortPreset: string; - fancyPageSelector: string; -} -export async function rearrangePages(params: RearrangePagesParamsType): Promise { - const { file, fancyPageSelector } = params; - - const pdfLibDocument = await file.pdfLibDocument; - - const pagesToExtractArray = parseFancyPageSelector(fancyPageSelector, pdfLibDocument.getPageCount()); - const newDocument = selectPages({file: file, pagesToExtractArray}); - return newDocument; -}; - -export type SelectPagesParamsType = { - file: PdfFile; - pagesToExtractArray: number[]; -} -export async function selectPages(params: SelectPagesParamsType): Promise { - const { file, pagesToExtractArray } = params; - - const pdfLibDocument = await file.pdfLibDocument; - - const subDocument = await PDFDocument.create(); - - // Check that array max number is not larger pdf pages number - if(Math.max(...pagesToExtractArray) >= pdfLibDocument.getPageCount()) { - throw new Error(`The PDF document only has ${pdfLibDocument.getPageCount()} pages and you tried to extract page ${Math.max(...pagesToExtractArray)}`); - } - - const copiedPages = await subDocument.copyPages(pdfLibDocument, pagesToExtractArray); - - for (let i = 0; i < copiedPages.length; i++) { - subDocument.addPage(copiedPages[i]); - } - - return new PdfFile(file.originalFilename, subDocument, RepresentationType.PDFLibDocument, file.filename); -} - -export type RemovePagesParamsType = { - file: PdfFile; - pagesToRemoveArray: number[]; -} -export async function removePages(params: RemovePagesParamsType): Promise { - const { file, pagesToRemoveArray } = params; - - const pdfLibDocument = await file.pdfLibDocument; - - const pagesToExtractArray = invertSelection(pagesToRemoveArray, pdfLibDocument.getPageIndices()) - return selectPages({file: file, pagesToExtractArray}); -} - -export type RemoveBlankPagesParamsType = { - file: PdfFile; - whiteThreashold: number; -} -export async function removeBlankPages(params: RemoveBlankPagesParamsType) { - const { file, whiteThreashold } = params; - - const emptyPages = await detectEmptyPages(file, whiteThreashold); - console.log("Empty Pages: ", emptyPages); - return removePages({file, pagesToRemoveArray:emptyPages}); -} - - -/** - * Parse the page selector string used in the 'PDF Page Organizer' - * @param pageOrderArr - * @param totalPages - * @returns - */ -function parseFancyPageSelector(pageNumbers: string, totalPages: number): number[] { - // Translated to JS from the original Java function - const pageOrderArr = pageNumbers.split(",") - const newPageOrder: number[] = []; - - // loop through the page order array - pageOrderArr.forEach(element => { - if (element.toLocaleLowerCase() === "all") { - for (var i = 0; i < totalPages; i++) { - newPageOrder.push(i); - } - // As all pages are already added, no need to check further - return; - } - else if (element.match("\\d*n\\+?-?\\d*|\\d*\\+?n")) { - // Handle page order as a function - var coefficient = 0; - var constant = 0; - var coefficientExists = false; - var constantExists = false; - - if (element.includes("n")) { - var parts = element.split("n"); - if (!parts[0]) { - coefficient = parseInt(parts[0]); - coefficientExists = true; - } - if (parts.length > 1 && parts[1]) { - constant = parseInt(parts[1]); - constantExists = true; - } - } else if (element.includes("+")) { - constant = parseInt(element.replace("+", "")); - constantExists = true; - } - - for (var i = 1; i <= totalPages; i++) { - var pageNum = coefficientExists ? coefficient * i : i; - pageNum += constantExists ? constant : 0; - - if (pageNum <= totalPages && pageNum > 0) { - newPageOrder.push(pageNum - 1); - } - } - } else if (element.includes("-")) { - // split the range into start and end page - const range = element.split("-"); - const start = parseInt(range[0]); - var end = parseInt(range[1]); - // check if the end page is greater than total pages - if (end > totalPages) { - end = totalPages; - } - // loop through the range of pages - for (var j = start; j <= end; j++) { - // print the current index - newPageOrder.push(j - 1); - } - } else { - // if the element is a single page - newPageOrder.push(parseInt(element) - 1); - } - }); - - return newPageOrder; -} - -function invertSelection(selection: number[], pageIndecies: number[]): number[] { - const pageIndeciesCopy = [...pageIndecies]; - return pageIndeciesCopy.filter(x => !selection.includes(x)); -} - -////////////////// -// Page Sorters // -////////////////// -function reverseSort(totalPages: number): number[] { - return [...Array(totalPages).keys()].reverse(); -} - -function duplexSort(totalPages: number): number[] { - // Translated to JS from the original Java function - const newPageOrder: number[] = []; - const half = Math.floor((totalPages + 1) / 2); // This ensures proper behavior with odd numbers of pages - - for (let i = 1; i <= half; i++) { - newPageOrder.push(i - 1); - if (i <= totalPages - half) { - // Avoid going out of bounds - newPageOrder.push(totalPages - i); - } - } - - return newPageOrder; -} - -function bookletSort(totalPages: number): number[] { - const newPageOrder: number[] = []; - for (let i = 0; i < totalPages / 2; i++) { - newPageOrder.push(i); - newPageOrder.push(totalPages - i - 1); - } - return newPageOrder; -} - -function sideStitchBooklet(totalPages: number): number[] { - const newPageOrder: number[] = []; - for (let i = 0; i < (totalPages + 3) / 4; i++) { - const begin = i * 4; - newPageOrder.push(Math.min(begin + 3, totalPages - 1)); - newPageOrder.push(Math.min(begin, totalPages - 1)); - newPageOrder.push(Math.min(begin + 1, totalPages - 1)); - newPageOrder.push(Math.min(begin + 2, totalPages - 1)); - } - return newPageOrder; -} - -function oddEvenSplit(totalPages: number): number[] { - const newPageOrder: number[] = []; - for (let i = 1; i <= totalPages; i += 2) { - newPageOrder.push(i - 1); - } - for (let i = 2; i <= totalPages; i += 2) { - newPageOrder.push(i - 1); - } - return newPageOrder; -} - -function removeFirst(totalPages: number): number[] { - return [...Array(totalPages-1).keys()].map(i => i+1); -} - -function removeLast(totalPages: number): number[] { - return [...Array(totalPages-1).keys()]; -} - -function removeFirstAndLast(totalPages: number): number[] { - return [...Array(totalPages-2).keys()].map(i => i+1); -} - -export type SortFunction = (totalPages: number) => number[]; -type Sorts = { - [key: string]: SortFunction; -}; -export const sorts: Sorts = Object.freeze({ - "REVERSE_ORDER": reverseSort, - "DUPLEX_SORT": duplexSort, - "BOOKLET_SORT": bookletSort, - "SIDE_STITCH_BOOKLET_SORT": sideStitchBooklet, - "ODD_EVEN_SPLIT": oddEvenSplit, - "REMOVE_FIRST": removeFirst, - "REMOVE_LAST": removeLast, - "REMOVE_FIRST_AND_LAST": removeFirstAndLast, -}); diff --git a/shared-operations/src/index.ts b/shared-operations/src/index.ts index f2e8acd1..abde097c 100644 --- a/shared-operations/src/index.ts +++ b/shared-operations/src/index.ts @@ -1,16 +1,12 @@ -import { - sortPagesWithPreset, SortPagesWithPresetParamsType, - rearrangePages, RearrangePagesParamsType, - selectPages, SelectPagesParamsType, - removePages, RemovePagesParamsType, - removeBlankPages, RemoveBlankPagesParamsType -} from "./functions/subDocumentFunctions"; +import { extractPages, ExtractPagesParamsType } from "./functions/extractPages"; import { impose, ImposeParamsBaseType, ImposeParamsType } from "./functions/impose"; import { mergePDFs, MergeParamsType } from './functions/mergePDFs'; +import { removeBlankPages, RemoveBlankPagesParamsType } from "./functions/removeBlankPages"; import { rotatePages, RotateParamsType } from './functions/rotatePages'; import { scaleContent, ScaleContentParamsType} from './functions/scaleContent'; import { scalePage, ScalePageParamsType } from './functions/scalePage'; +import { sortPagesWithPreset, SortPagesWithPresetParamsType } from './functions/sortPagesWithPreset' import { splitOn, SplitOnParamsType } from './functions/splitOn'; import { splitPDF, SplitPdfParamsType } from './functions/splitPDF'; import { updateMetadata, UpdateMetadataParams } from "./functions/updateMetadata"; @@ -21,12 +17,14 @@ import { Override } from '../declarations/TypeScriptUtils' // Import injected libraries here! const toExport = { - sortPagesWithPreset, rearrangePages, selectPages, removePages, removeBlankPages, + extractPages, impose, mergePDFs, + removeBlankPages, rotatePages, scaleContent, scalePage, + sortPagesWithPreset, splitOn, splitPDF, updateMetadata, @@ -34,16 +32,14 @@ const toExport = { export default toExport; export type OperationsParametersBaseType = { - sortPagesWithPreset: SortPagesWithPresetParamsType; - rearrangePages: RearrangePagesParamsType; - selectPages: SelectPagesParamsType; - removePages: RemovePagesParamsType; - removeBlankPages: RemoveBlankPagesParamsType; + extractPages: ExtractPagesParamsType; impose: ImposeParamsBaseType; mergePDFs: MergeParamsType; + removeBlankPages: RemoveBlankPagesParamsType; rotatePages: RotateParamsType; scaleContent: ScaleContentParamsType; scalePage: ScalePageParamsType; + sortPagesWithPreset: SortPagesWithPresetParamsType; splitOn: SplitOnParamsType; splitPDF: SplitPdfParamsType; updateMetadata: UpdateMetadataParams; diff --git a/shared-operations/src/workflow/traverseOperations.ts b/shared-operations/src/workflow/traverseOperations.ts index 004d53ad..612e7118 100644 --- a/shared-operations/src/workflow/traverseOperations.ts +++ b/shared-operations/src/workflow/traverseOperations.ts @@ -54,7 +54,7 @@ export async function * traverseOperations(operations: Action[], input: PdfFile[ break; case "extract": yield* nToN(input, action, async (input) => { - const newPdf = await Operations.selectPages({file: input, pagesToExtractArray: action.values["pagesToExtractArray"]}); + const newPdf = await Operations.extractPages({file: input, pageIndexes: action.values["pageIndexes"]}); newPdf.filename += "_extractedPages"; return newPdf; }); @@ -96,7 +96,7 @@ export async function * traverseOperations(operations: Action[], input: PdfFile[ break; case "sortPagesWithPreset": yield* nToN(input, action, async (input) => { - const newPdf = await Operations.sortPagesWithPreset({file: input, sortPreset: action.values["sortPreset"], fancyPageSelector: action.values["fancyPageSelector"]}); + const newPdf = await Operations.sortPagesWithPreset({file: input, sortPreset: action.values["sortPreset"]}); newPdf.filename += "_pagesOrganized"; return newPdf; });