skaldjciareio

PDFMerge

Jul 20th, 2020
201
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #NoEnv
  2. SendMode Input
  3. SetWorkingDir %A_ScriptDir%
  4.  
  5. ; This script only works on Windows 10 or later
  6. If (!RegExMatch(A_OsVersion, "\d+\.\d+\.\d+"))
  7. {
  8.     MsgBox This script requires Windows 10.
  9.     ExitApp
  10. }
  11.  
  12. ; ================= Setup =================
  13. ; Indicates if there were any files copied to the temp location
  14. tempLocationUsed := False
  15. ; If the user wants to override a source file save the location
  16. tempOverrideLocation := ""
  17. ; All pdf input files
  18. pdfArray := []
  19. ; The name of the new file
  20. pdfOutputName := "result"
  21. ; The path to the new file
  22. pdfOutputPath := A_ScriptDir
  23.  
  24.  
  25. ; ================= Main =================
  26. If (!FileExist(A_ScriptDir . "\pdftk.exe"))
  27. {
  28.     MsgBox, 4, Error, "pdftk"could not be found`nShow download instructions?
  29.     IfMsgBox, Yes
  30.     {
  31.         Gui, Font, s10
  32.         Gui, Add, Link, y+20, 1. Download pdftk portable from <a href="https://portableapps.com/de/apps/office/pdftk_builder_portable#">this website</a>.
  33.         Gui, Add, Text, y+7, 2. Double click the file, it will extract itself.
  34.         Gui, Add, Text, y+7, 3. In the folder "PDFTKBuilderPortable\App\pdftkbuilder" extract the file "pdftk.exe".
  35.         Gui, Add, Text, y+7, 4. Put this file in the same folder as this script.
  36.         Gui, Add, Text, y+7, 5. The downloaded and extracted files/folders are not needed anymore.
  37.         Gui, Add, Button, gGuiClose w80 y+20, Ok
  38.         Gui, Show, , Download pdftk
  39.         Return
  40.     }
  41.     Else
  42.     {
  43.         Exitapp
  44.     }
  45. }
  46.  
  47. MsgBox, Select all documents you want to concatenate in a file explorer window and press ctrl + p.
  48. Return
  49.  
  50. GuiClose:
  51. GuiEscape:
  52. Exitapp
  53.  
  54. #IfWinActive, ahk_class CabinetWClass ahk_exe explorer.exe
  55. ^p::
  56.  
  57.     ; Clear Clipboard and refill it after
  58.     Clipboard := ""
  59.     Sleep, 50
  60.     Send, ^c
  61.     Sleep, 50
  62.  
  63.     ; Check if the clipboard holds data
  64.     If (ErrorLevel || !ClipboardError())
  65.     {
  66.         MsgBox, 16, Error, Please mark images or PDF files in Windows Explorer.
  67.         Return
  68.     }
  69.  
  70.     ; Find the path to save the file to
  71.     pdfOutputPath := FindFinalPdfPath()
  72.  
  73.     ; Check for available names for the final file
  74.     pdfOutputName := FindFinalPdfName()
  75.    
  76.     ; Let the user decide for a new name
  77.     If (pdfOutputName != "result.pdf")
  78.     {
  79.         MsgBox, 51, File already exists, There is already a file called "result.pdf".`nShould the file be saved as "%pdfOutputName%"?
  80.         IfMsgBox, Cancel
  81.         {
  82.             ExitApp
  83.         }
  84.         IfMsgBox, Yes
  85.         {
  86.             pdfOutputName := pdfOutputPath . "\" . pdfOutputName
  87.         }
  88.         IfMsgBox, No
  89.         {
  90.             selectNameSuccess := False
  91.             ; Try to find a new name for the file
  92.             While, !selectNameSuccess
  93.             {
  94.                 ; Let the user select a new file
  95.                 FileSelectFile, pdfOutputName, S, %pdfOutputPath%, , PDF-Documents (*.pdf)
  96.  
  97.                 ; Make sure the user selected a file
  98.                 If (pdfOutputName = "")
  99.                 {
  100.                     MsgBox, 49, Select a name, Please give the file a name.
  101.                     IfMsgBox, Cancel
  102.                     {
  103.                         ExitApp
  104.                     }
  105.                     IfMsgBox, Ok
  106.                     {
  107.                         ; Let the user select a new file
  108.                         FileSelectFile, pdfOutputName, S, %pdfOutputPath%, , PDF-Documents (*.pdf)
  109.                     }
  110.                 }
  111.  
  112.                 SplitPath, pdfOutputName, OutFileName,, OutExtension, OutNameNoExt
  113.                 ; Make sure the extension is ".pdf"
  114.                 If (OutExtension != "pdf")
  115.                 {
  116.                     pdfOutputName := OutNameNoExt . ".pdf"
  117.                 }
  118.                 ; Look for a file with the same name
  119.                 If (NameIsAlreadyInFolder(pdfOutputName))
  120.                 {
  121.                     MsgBox, 52, File is already in folder, There is already a file with the name "%OutFileName%".`nShould it be replaced?
  122.                     IfMsgBox, Yes
  123.                     {
  124.                         ; Check if the selected file is a source file
  125.                         If (InStr(Clipboard, pdfOutputName))
  126.                         {
  127.                             ; Copy the file to A_Temp\AutoHotKey\PDFMerge_noGui\FILENAME.pdf
  128.                             ; Path to the temp file
  129.                             tempLocation := A_Temp . "\AutoHotKey\PDFMerge_noGui\"
  130.                             ; Create the directory
  131.                             FileCreateDir, %tempLocation%
  132.                             ; The new name and path
  133.                             filePath := tempLocation . OutFileName
  134.                             ; Copy the file to the new path
  135.                             FileCopy, %pdfOutputName%, %filePath%
  136.                             If (ErrorLevel)
  137.                             {
  138.                                 MsgBox, 16, Error, File could not be replaced, program will exit
  139.                                 ExitApp
  140.                             }
  141.                             tempLocationUsed := True
  142.                            
  143.                             ; Save the location of the deleted file
  144.                             ; It will be inserted later in the clipboard parse process
  145.                             tempOverrideLocation := filePath
  146.                         }
  147.                         ; Delete the current file to make up the space for the new one, because pdftk cannot override an existing file
  148.                         FileDelete, %pdfOutputName%
  149.                         If (ErrorLevel)
  150.                         {
  151.                             MsgBox, 16, Error, File could not be deleted, program will exit
  152.                             ExitApp
  153.                         }
  154.                         selectNameSuccess := True
  155.                     }
  156.                     IfMsgBox, No
  157.                     {
  158.                         MsgBox, 64, Change name, Please give the file another name.
  159.                     }
  160.                 }
  161.                 ; Make sure the user specified a name
  162.                 Else If (pdfOutputName = ".pdf")
  163.                 {
  164.                 }
  165.                 ; A name was found
  166.                 Else
  167.                 {
  168.                     selectNameSuccess := True
  169.                     pdfOutputName := pdfOutputPath . "\" . pdfOutputName
  170.                 }
  171.             }
  172.         }
  173.     }
  174.     Else
  175.     {
  176.         pdfOutputName := pdfOutputPath . "\" . pdfOutputName
  177.     }
  178.  
  179.     ; Sort the clipboard (if the sorting option in the explorer was e.g. set to "Date")
  180.     Sort, Clipboard
  181.     ; Counts the added files and adds them at the right place into the array
  182.     loopCounter := 1
  183.     ; Parse the clipboard and get every filename
  184.     Loop, Parse, Clipboard, `n, `r
  185.     {
  186.         ; If one of the files is an image we have to convert it to pdf
  187.         SplitPath, A_LoopField,,, OutExtension, OutNameNoExt
  188.  
  189.         ; Find every image in the list and print it to pdf and then add it to the list
  190.         If OutExtension in png,dib,jpg,jpeg,jpe,jfif,gif,tif,tiff,png,ico,heic,webp
  191.         {
  192.             tempLocationUsed := True
  193.             filePath := printToPdf(A_LoopField)
  194.             pdfArray[loopCounter] := filePath
  195.             loopCounter++
  196.         }
  197.  
  198.         ; If the file type is pdf, add it to the list directly
  199.         If (OutExtension = "pdf")
  200.         {
  201.             If (A_LoopField = pdfOutputName)
  202.             {
  203.                 pdfArray[loopCounter] := tempOverrideLocation
  204.             }
  205.             Else
  206.             {
  207.                 ; Add every pdf file to the list
  208.                 pdfArray[loopCounter] := A_LoopField
  209.             }
  210.             loopCounter++
  211.         }
  212.     }
  213.  
  214.     ; The final command
  215.     pdfMergeCommand := GenerateCatCommand(pdfArray) . """" . pdfOutputName . """"
  216.  
  217.     ; Run the command to generate the file
  218.     Run, cmd.exe /c pdftk %pdfMergeCommand%, , Hide
  219.  
  220.     ; Wait for the file to exist before the program proceeds and cleans up
  221.     While (!FileExist(pdfOutputName))
  222.     {
  223.         Sleep, 100
  224.     }
  225.  
  226.     ; If an image was found or any other files were copied, the temp files have to be removed
  227.     If (tempLocationUsed)
  228.     {
  229.         FileRemoveDir, %A_Temp%\AutoHotKey\PDFMerge_noGui\, True
  230.  
  231.         ; Check if there is another folder or file inside of the "AutoHotKey" folder
  232.         ; Only happens if another script ran and saved data to Temp
  233.         foundDir := False
  234.         Loop, Files, %A_Temp%\AutoHotKey\*.*, D F
  235.         {
  236.             If (A_LoopFileName > 1)
  237.             {
  238.                 foundDir := True
  239.                 Break
  240.             }
  241.         }
  242.         ; If the folder is now empty, delete it
  243.         If (!foundDir)
  244.         {
  245.             FileRemoveDir, %A_Temp%\AutoHotKey\, True
  246.         }
  247.     }
  248.  
  249.     ExitApp
  250.  
  251. ; ================== Helper functions =================
  252.  
  253. ; Extracts all names out of the input array and generates a command
  254. GenerateCatCommand(names)
  255. {
  256.     result := ""
  257.     Loop, % names.Length()
  258.     {
  259.         result .= """" . names[A_Index] . """ "
  260.     }
  261.  
  262.     result .= "cat output "
  263.     Return result
  264. }
  265.  
  266. ; Prints the file as pdf and temporarily saves it in %Temp%\AutoHotKey\FILENAME.pdf
  267. printToPdf(fileToPrint)
  268. {
  269.     ; Path to the temp file
  270.     tempLocation := A_Temp . "\AutoHotKey\PDFMerge_noGui\"
  271.     ; Create the directory
  272.     FileCreateDir, %tempLocation%
  273.     ; Filename
  274.     SplitPath, fileToPrint,,,, OutNameNoExt
  275.     filePath := tempLocation . OutNameNoExt . "_img.pdf"
  276.     Sleep, 1000
  277.  
  278.     ; Print the file
  279.     Run, cmd.exe /c mspaint /p "%fileToPrint%" /pt "Microsoft Print to PDF"
  280.  
  281.     ; Save the pdf file
  282.     WinWaitActive, ahk_class #32770
  283.     SendInput, %filePath%
  284.     Sleep, 50
  285.     Send, {Enter}
  286.  
  287.     ; Wait until Paint is closed
  288.     While, (WinExist("ahk_exe mspaint.exe"))
  289.     {
  290.         Sleep, 100
  291.     }
  292.     return filePath
  293. }
  294.  
  295. ; Finds out the best name for the new generated file
  296. FindFinalPdfName()
  297. {
  298.     global pdfOutputPath
  299.  
  300.     regExFileMatch := False
  301.     normalFileMatch := False
  302.     regExFileNames := ""
  303.  
  304.     ; Check if the pdfOutputPath contains a "result.pdf" or a "result (\d+).pdf" file
  305.     Loop, Files, %pdfOutputPath%\*.pdf
  306.     {
  307.  
  308.         If (RegExMatch(A_LoopFileName, "i)result \(\d+\)\.pdf") == 1)
  309.         {
  310.             regExFileMatch := True
  311.             ; Add each found number to a list
  312.             regExFileNames .= SubStr(A_LoopFileName, 9, InStr(A_LoopFileName, ")",, 10) - InStr(A_LoopFileName, "(",, 8) - 1) . ","
  313.         }
  314.         If (A_LoopFileName = "result.pdf")
  315.         {
  316.             normalFileMatch := True
  317.         }
  318.     }
  319.  
  320.     ; Sort the list of the found numbers numerically
  321.     Sort, regExFileNames, N D,
  322.  
  323.     If (!normalFileMatch)
  324.     {
  325.         Return "result.pdf"
  326.     }
  327.     Else If (normalFileMatch && !regExFileMatch)
  328.     {
  329.         Return "result (1).pdf"
  330.     }
  331.     Else If (normalFileMatch && regExFileMatch)
  332.     {
  333.         ; Split the string into an array
  334.         temp := StrSplit(regExFileNames, ",")
  335.        
  336.         ; Loop through every item in the list
  337.         Loop, % temp.Count()
  338.         {
  339.             ; Find the smallest available number
  340.             If (temp[A_Index] != A_Index)
  341.             {
  342.                 Return "result (" . A_Index . ").pdf"
  343.             }
  344.         }
  345.         ; If no number in between was found return the next smallest number
  346.         Return temp[temp.Count()] + 1
  347.     }
  348.     Else
  349.     {
  350.         Return "result.pdf"
  351.     }
  352. }
  353.  
  354. ; Finds the folder location for the new generated file
  355. FindFinalPdfPath()
  356. {
  357.     Loop, Parse, Clipboard, `n, `r
  358.     {
  359.         ; As all files are in the same folder, we can use the first occurence of the link and get the path
  360.         SplitPath, A_LoopField,, OutDir
  361.         Return OutDir
  362.     }
  363.  
  364. }
  365.  
  366. ; Checks if an element with the same name is already in the folder
  367. NameIsAlreadyInFolder(fileName)
  368. {
  369.     SplitPath, fileName,, OutDir
  370.     Loop, Files, %OutDir%\*.pdf
  371.     {
  372.         If (fileName = A_LoopFileFullPath)
  373.         {
  374.             Return 1
  375.         }
  376.     }
  377.     Return 0
  378. }
  379.  
  380. ; Checks if the Clipboard contains only legal strings (only paths are valid)
  381. ClipboardError()
  382. {
  383.     If (Clipboard = "")
  384.     {
  385.         Return 0
  386.     }
  387.  
  388.     Loop, Parse, Clipboard, `n, `r
  389.     {
  390.         SplitPath, A_LoopField, OutFileName, OutDir, OutExtension, OutNameNoExt, OutDrive
  391.         If (OutFileName = "" || OutDir = "" || OutExtension = "" || OutNameNoExt = "" || OutDrive = "")
  392.         {
  393.             Return 0
  394.         }
  395.     }
  396.     Return 1
  397. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×