Skip to content

Instantly share code, notes, and snippets.

@StudioEtrange
Last active January 19, 2025 15:18
Show Gist options
  • Save StudioEtrange/44a2fb333f4d682ab72634c3dd9e472f to your computer and use it in GitHub Desktop.
Save StudioEtrange/44a2fb333f4d682ab72634c3dd9e472f to your computer and use it in GitHub Desktop.
various pdf manipulation tools and tips

various tips and tools for pdf

@echo off
@setlocal enableExtensions disableDelayedExpansion
set "arg1=%~1"
set "arg2=%~2"
set "arg3=%~3"
set "arg4=%~4"
@setlocal enableDelayedExpansion
set "CURRENT_RUNNING_DIR=%cd%"
echo Source code is here : https://gist.github.com/StudioEtrange/44a2fb333f4d682ab72634c3dd9e472f
echo Will remove text from pdf inside a folder. Will modfiy specified file or all files in folder and subfolders.
echo Need tool 'a-pdf text replace' installed http://www.a-pdf.com/text-replace/index.htm
echo Usage : %~nx0 "apdf_exe_full_path" "pdf_folder_or_file" "regexp_text_to_remove" "<OPTIONS>"
echo Option list :
echo BACKUP : backup the transformed files as .backup.pdf files
echo REGEX : use the third arg as a regex to match text to remove (default active option)
echo REGEX_FILE : use the third arg as a path to file containing several regexes, one by line
echo REGEX_FILE FORMAT : these two lines will be merged into one regex "((R|r)ef)?(word)?"
echo ## a comment
echo (R^|r)ef
echo ## another comment
echo word
echo Sample : %~nx0 "e:\Program Files (x86)\A-PDF Text Replace\ptrcmd.exe" "E:\TO_MODIFY\files" "[0-9]{6,8}[/]?[0-9]*/[0-9]*/[0-9]{5,6}" "BACKUP"
echo Sample : %~nx0 "e:\Program Files (x86)\A-PDF Text Replace\ptrcmd.exe" "E:\TO_MODIFY\files" "E:\regex.txt" "BACKUP REGEX_FILE"
echo -------
echo CALL apdf_remove_text "!arg1!" "!arg2!" "!arg3!" "!arg4!"
call :apdf_remove_text "!arg1!" "!arg2!" "!arg3!" "!arg4!"
@goto :end
:apdf_remove_text
@setlocal disableDelayedExpansion
set "apdfexe_path=%~1"
set "pdf_path=%~2"
set "arg=%~3"
set "opt=%~4"
@setlocal enableDelayedExpansion
set "backup="
set "regex="
set "regex_file="
REM by default the arg is a regex
set "_flag_regex=ON"
set "_flag_file_regex="
for %%O in (%opt%) do (
if "%%O"=="BACKUP" (
set "backup=.backup.pdf"
)
if "%%O"=="WORKSPACE" (
set _opt_share_workspace=ON
)
if "%%O"=="REGEX" (
set "_flag_regex=ON"
set "_flag_file_regex="
)
if "%%O"=="REGEX_FILE" (
set "_flag_regex="
set "_flag_file_regex=ON"
)
)
if "!_flag_file_regex!"=="ON" (
set "regex="
set "regex_file=!arg!"
if exist "!regex_file!" (
echo BEGIN loading regex file !regex_file!
for /f "delims=" %%L in (!regex_file!) do (
set "l=%%L"
if not "!l:~0,2!"=="##" (
echo Loading regex : %%L
set "regex=!regex!(%%L)?"
) else (
echo Comment : %%L
)
)
echo END loading regex file !regex_file!
) else (
echo File !regex_file! do not exist
goto :end
)
) else (
set "regex=!arg!"
set "regex_file="
)
if not "!regex!"=="" (
echo Will remove "!regex!"
echo From "%~2"
echo -------
set "attr=%~a2"
set "dirattr=!attr:~0,1!"
if /I "!dirattr!"=="d" (
cd /D "!pdf_path!"
for /R %%p in ("*.pdf") do (
echo Found file : %%p
if not "!backup!"=="" (
@copy /y "%%p" "%%p!backup!" >nul 2>&1
)
REM echo "!apdfexe_path!" "%%p" "%%p" "!regex!" "$EMPTY$" -EY -CY
"!apdfexe_path!" "%%p" "%%p" "!regex!" "$EMPTY$" -EY -CY
)
) else (
set "extension=%~x2"
if "!extension!"==".pdf" (
if not "!backup!"=="" (
@copy /y "!pdf_path!" "!pdf_path!!backup!" >nul 2>&1
)
REM echo "!apdfexe_path!" "!pdf_path!" "!pdf_path!" "!regex!" "$EMPTY$" -EY -CY
"!apdfexe_path!" "!pdf_path!" "!pdf_path!" "!regex!" "$EMPTY$" -EY -CY
)
)
) else (
echo Error : Empty regex
goto :end
)
goto :eof
:end
@cd /D "%CURRENT_RUNNING_DIR%"
@echo on
@echo off
@setlocal enableExtensions disableDelayedExpansion
REM support UTF8 characters print for qpdf error output strings
@chcp 65001 > nul
REM batch command use path prefixed by \\?\c:\path to bypass file path size max limit
REM https://superuser.com/a/825233
set "arg1=%~1"
set "arg2=%~2"
set "arg3=%~3"
@setlocal enableDelayedExpansion
set "CURRENT_RUNNING_DIR=%cd%"
echo Source code is here : https://gist.github.com/StudioEtrange/44a2fb333f4d682ab72634c3dd9e472f
echo Will remove owner password on pdf files to allow modification
echo Will modfiy specified file or all files in folder and subfolder.
echo Need tool 'qpdf' installed https://github.com/qpdf/qpdf
echo Usage : %~nx0 "qpdf_exe_full_path" "pdf_files_or_folder_to_unprotect" "<OPTIONS>"
echo NOTE : support filepath with special character "!" inside
echo Option list :
echo BACKUP : backup the transformed files as .backup.pdf files
echo Sample : %~nx0 "T:\TOOLS\qpdf - pdf password remover opensource\qpdf-11.9.1-mingw64\bin\qpdf.exe" "T:\TO_UNPROTECT\files" "BACKUP"
echo -------
echo CALL unprotect "!arg1!" "!arg2!" "!arg3!"
call :unprotect "!arg1!" "!arg2!" "!arg3!"
@goto :end
REM qpdf option --replace-input do not work well
REM qpdf do not want to create file with .pdf extension in unknow circonstances (error : permission denied)
:unprotect
@setlocal disableDelayedExpansion
set "qpdfexe_path=%~1"
set "pdf_path=%~2"
set "backup=%~3"
@setlocal enableDelayedExpansion
set "extbackup=.backup.pdf"
if "!backup!"=="BACKUP" (
set "backup=%extbackup%"
) else (
set "backup="
)
set "attr=%~a2"
set "dirattr=%attr:~0,1%"
if /I "%dirattr%"=="d" (
cd /D "!pdf_path!"
for /R %%p in ("*.pdf") do (
setlocal DisableDelayedExpansion
set "extension=%%~xp"
set "_p=%%p"
setlocal EnableDelayedExpansion
for /F "delims=" %%A in ("!_p!\.") do (
setlocal DisableDelayedExpansion
set "_base=%%~nA"
setlocal EnableDelayedExpansion
set "basename_path=!_base!"
)
for /F "delims=" %%A in ("!_p!\.") do (
setlocal DisableDelayedExpansion
set "_dir=%%~dpA"
setlocal EnableDelayedExpansion
set "dir_path=!_dir!"
)
if not "%backup%"=="" (
echo -
echo BACKUP !_p! to !_p!!extbackup!
@copy /y "\\?\!_p!" "\\?\!_p!!extbackup!" >nul 2>&1
)
REM copy file into temp directory because there is a max limit to file path length that qpdf can read (max 260 characters)
copy /y "\\?\!_p!" "%TEMP%\!basename_path!!extension!" >nul 2>&1
echo -
echo "!qpdfexe_path!" --verbose --decrypt "!_p!" "!dir_path!!basename_path!.decrypted"
echo "!qpdfexe_path!" --verbose --decrypt "%TEMP%\!basename_path!!extension!" "%TEMP%\!basename_path!.decrypted"
echo -
"!qpdfexe_path!" --verbose --decrypt "%TEMP%\!basename_path!!extension!" "%TEMP%\!basename_path!.decrypted"
move /y "%TEMP%\!basename_path!.decrypted" "\\?\!dir_path!!basename_path!!extension!" >nul 2>&1
del "%TEMP%\!basename_path!!extension!" >nul 2>&1
del "%TEMP%\!basename_path!.decrypted" >nul 2>&1
)
) else (
set "extension=%~x2"
if "!extension!"==".pdf" (
for /F "delims=" %%A in ("!pdf_path!\.") do (
setlocal DisableDelayedExpansion
set "_base=%%~nA"
setlocal EnableDelayedExpansion
set "basename_path=!_base!"
)
for /F "delims=" %%A in ("!pdf_path!\.") do (
setlocal DisableDelayedExpansion
set "_dir=%%~dpA"
setlocal EnableDelayedExpansion
set "dir_path=!_dir!"
)
if not "%backup%"=="" (
echo -
echo BACKUP !pdf_path! to !pdf_path!!extbackup!
@copy /y "\\?\!dir_path!!basename_path!!extension!" "\\?\!dir_path!!basename_path!!extension!!extbackup!" >nul 2>&1
)
REM copy file into temp directory because there is a max limit to file path length that qpdf can read (max 260 characters)
echo copy /y "\\?\!dir_path!!basename_path!!extension!" "%TEMP%\!basename_path!!extension!"
copy /y "\\?\!dir_path!!basename_path!!extension!" "%TEMP%\!basename_path!!extension!" >nul 2>&1
echo -
echo "!qpdfexe_path!" --verbose --decrypt "!pdf_path!" "!dir_path!\!basename_path!.decrypted"
echo "!qpdfexe_path!" --verbose --decrypt "%TEMP%\!basename_path!!extension!" "%TEMP%\!basename_path!.decrypted"
echo -
"!qpdfexe_path!" --verbose --decrypt "%TEMP%\!basename_path!!extension!" "%TEMP%\!basename_path!.decrypted"
move /y "%TEMP%\!basename_path!.decrypted" "\\?\!dir_path!!basename_path!!extension!" >nul 2>&1
del "%TEMP%\!basename_path!!extension!" >nul 2>&1
del "%TEMP%\!basename_path!.decrypted" >nul 2>&1
)
)
goto :eof
:end
@cd /D %CURRENT_RUNNING_DIR%
@echo on
@setlocal enableExtensions enableDelayedExpansion
@echo off
set CURRENT_RUNNING_DIR=%cd%
echo Source code is here : https://gist.github.com/StudioEtrange/44a2fb333f4d682ab72634c3dd9e472f
echo Will split in two each poster of pdf files
echo need mupdf https://mupdf.com/
echo Usage : split_half_poster.bat "mutool_exe_full_path" "pdf_folder_to_split"
echo Sample : split_half_poster.bat "E:\WORKSPACE\mupdf-1.18.0-windows\mutool.exe" "E:\TO_SPLIT\files"
call :split "%~1" "%~2"
@goto :end
:del_folder
if exist "%~1" (
echo ** Deleting %~1 folder
del /f/q "%~1" >nul 2>&1
rmdir /s/q "%~1" >nul 2>&1
)
goto :eof
:basename
set "_result_basename=%~1"
set "_path=%~2"
for /F "delims=" %%A in ("!_path!\.") do (
set %_result_basename%=%%~nA
)
goto :eof
:dirname
set "_result_dirname=%~1"
set "_path=%~2"
for /F "delims=" %%A in ("!_path!\.") do (
set %_result_dirname%=%%~dpA
)
goto :eof
:split
set "exe_path=%~1"
set "pdf_folderpath=%~2"
call :dirname "output_path" "%pdf_folderpath%"
call :basename "basename_path" "%pdf_folderpath%"
set "output=%output_path%\%basename_path%_splitted"
call :del_folder "%output%"
mkdir "%output%"
cd /D "%pdf_folderpath%"
for %%p in ("*") do (
set "extension=%%~xp"
if "!extension!"==".pdf" (
echo "%exe_path%" poster -x 2 "%%p" "%output%\%%p"
"%exe_path%" poster -x 2 "%%p" "%output%\%%p"
) else (
echo copy /y "%%p" "%output%\%%p"
@copy /y "%%p" "%output%\%%p"
)
)
goto :eof
:end
@cd /D %CURRENT_RUNNING_DIR%
@echo on
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment