' ========================================================================== ' Name: PDF Metadata Editor ' Version: 1.1 ' Last Modified: 2005-05-31 ' Program URL: http://www.arilabs.com/software/pdfmeta/pdfmeta.vbs ' Filename: pdfmeta.vbs ' Author: Brian High ' Copyright: Analytical Resources, Inc. (2005) ' License: GNU GPL version 2 (or greater). See LICENSE section below. ' Description: It allows you to edit Title, Author, Subject, and Keywords. ' It is an easy to use, but limited front end to pdftk. ' Requires: pdftk-1.12, VBScript language support (Windows Script Host) ' ========================================================================== ' ============ ' Instructions ' ============ ' (1) Requires this script (pdfmeta.vbs) to be in same folder as pdftk.exe. ' The easiest way to install pdftk is to install "PDFTK Builder" (free). ' http://users.on.net/~johnson/pdftkb/pdftkb_setup.exe ' PDFTK Builder is a GUI front end for pdftk and has many useful features. ' --Or-- you can unzip pdftk.exe from the zip file found here: ' http://www.accesspdf.com/pdftk/ (Click Download link and get zip.) ' (Place pdftk.exe in an appropriately named and located folder.) ' See also: http://hacks.oreilly.com/pub/h/2422 ' (2) Place this script (pdfmeta.vbs) in the installation folder for the ' pdftk package. Make a shortcut to pdfmeta.vbs and place on your ' desktop, if you like. ' (3) USAGE: Just drag the source PDF file onto this VBS script (or a ' shortcut to it). Follow prompts. The temporary folder will open ' and the new PDF will be inside. Move the new PDF to its destination. ' ==================================================================== ' LICENSE: GNU GPL v2 or greater: http://www.gnu.org/licenses/gpl.txt ' ==================================================================== ' This program is free software; you can redistribute it and/or modify ' it under the terms of the GNU General Public License as published by ' the Free Software Foundation; either version 2 of the License, or ' (at your option) any later version. ' ' This program is distributed in the hope that it will be useful, ' but WITHOUT ANY WARRANTY; without even the implied warranty of ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ' GNU General Public License for more details. Option Explicit ' Declare Variables Dim sInfile, sFileName, sTempFile, sCurrentDir, sCurrentDrive, sScriptName Dim sComSpec, sMeta, sTempPath, sCmd, sPdftk, sAppTitle, sTKCmd, args ' Configure application title and filename of PDFTK command sAppTitle = "PDF Metadata Editor v1.1" sTKCmd = "pdftk.exe" ' To use different metadata fields, change this array definition Dim aFields(3,1) aFields(0,0) = "Title" aFields(1,0) = "Subject" aFields(2,0) = "Author" aFields(3,0) = "Keywords" ' Set flag for "dictionary not found" Dim noDict noDict = False ' Define Constants Const Create = True, DontCreate = False Const HideWindow = 0, ShowWindow = 1 Const ForReading = 1, ForWriting = 2, ForAppending = 3 ' Main Routine GetArguments() OpenPDFFile() GetCurrentDirectory() TryToAccessPDFTK() GetTempFolder() DeleteMetaFile() CreateDumpDataCmd() WriteMetaData() DisplayMetaData() PromptForMetaData() WriteNewMetaData() WriteMetaDataIntoNewPDF() ' Subroutines Private Sub GetArguments Dim sErr, num, oShell ' Get script arguments and check for at least one (the file name) Set oShell = WScript.CreateObject("WScript.Shell") Set args = WScript.Arguments sScriptName = WScript.ScriptFullName num = args.Count sErr = "Usage: [cscript | wscript] pdfmeta.vbs " & vbCRLF & _ "(Just drag a PDF file onto this script and follow the prompts.)" If num = 0 Then WScript.Echo sErr WScript.Quit 1 End If If InStr(UCase(args.Item(0)), ".PDF") = 0 Then WScript.Echo sErr WScript.Quit 1 End If End Sub Private Sub OpenPDFFile Dim sErr, sFile, oFile, FSO ' Try to open the input file Set FSO = WScript.CreateObject("Scripting.FileSystemObject") sFile = args.Item(0) sErr = sFile & " does not exist!" If FSO.FileExists(sFile) Then Set oFile = FSO.GetFile(sFile) sInfile = oFile.path sFileName = oFile.name Else WScript.Echo sErr WScript.Quit 1 End If End Sub Private Sub GetCurrentDirectory Dim aCurrentPath, FSO, sErr, oFile ' Get current directory (where script is located) Set FSO = WScript.CreateObject("Scripting.FileSystemObject") Set oFile = FSO.GetFile(sScriptName) sCurrentDir = oFile.path aCurrentPath = split(sCurrentDir, ":") sCurrentDrive = aCurrentPath(0) sErr = "This program must reside on a local drive or mapped drive." If Len(sCurrentDrive) <> 1 Then WScript.Echo sErr WScript.Quit 1 End If sCurrentDir = aCurrentPath(1) sCurrentDir = Mid(sCurrentDir, 1, Len(sCurrentDir) - Len(oFile.name)) sPdftk = sCurrentDrive & ":" & sCurrentDir & sTKCmd End Sub Private Sub TryToAccessPDFTK Dim sErr, FSO ' Try to access the pdftk.exe program Set FSO = WScript.CreateObject("Scripting.FileSystemObject") sErr = sPdftk & " does not exist!" If FSO.FileExists(sPdftk) Then ' Found pdftk.exe in current directory... Else WScript.Echo sErr WScript.Quit 1 End If End Sub Private Sub GetTempFolder Dim oShell ' Get the path of the temporary folder set oShell = CreateObject("WScript.Shell") sTempPath = oShell.ExpandEnvironmentStrings("%temp%") sComSpec = oShell.ExpandEnvironmentStrings("%comspec%") sTempFile = sTempPath & "\" & sFileName End Sub Private Sub DeleteMetaFile Dim FSO, oOrigMetaFile ' Delete the metadata file if it already exists sMeta = sTempPath & "\metadata.txt" Set FSO = CreateObject("Scripting.FileSystemObject") If FSO.FileExists(sMeta) Then Set oOrigMetaFile = FSO.GetFile(sMeta) oOrigMetaFile.Delete End If End Sub Private Sub CreateDumpDataCmd Dim oShell ' Create a command shell object and dump pdf info to metadata file sCmd = sComSpec & " /c chdir /d """ & sCurrentDrive & ":" & sCurrentDir _ & """ & " & sTKCmd & " """ & sInfile & """ dump_data " _ & ">""" & sMeta & """ 2>&1" Set oShell = WScript.CreateObject("Wscript.Shell") oShell.Run sCmd, HideWindow, True End Sub Private Sub FixBrokenDictionary Dim oShell ' Create a command shell object and "cat" pdf info new pdf sCmd = """" & sPdftk & """" & " " & """" & sInfile & """" & _ " cat output " & """" & sTempFile & """" & " dont_ask" Set oShell = WScript.CreateObject("Wscript.Shell") oShell.Run sCmd, HideWindow, True sCmd = sComSpec & " /c move /y " & """" & sTempFile & """" & " " & """" _ & sInfile & """" Set oShell = WScript.CreateObject("Wscript.Shell") oShell.Run sCmd, HideWindow, True CreateDumpDataCmd() WriteMetaData() End Sub Private Sub WriteMetaData Dim RE, FSO, TSO, sErr sErr = "Unable to repair info dictionary." ' Read from metadata file, test for expressions, ' and store metadata values Set FSO = CreateObject("Scripting.FileSystemObject") If FSO.FileExists(sMeta) Then Set TSO = FSO.OpenTextFile(sMeta, ForReading, DontCreate) Set RE = New RegExp Dim i, sLine Do While Not TSO.AtEndOfStream sLine = TSO.ReadLine RE.Pattern = "no info dictionary found" If RE.Test(sLine) Then If noDict = True Then WScript.Echo sErr WScript.Quit 1 Else noDict = True ' Close TextStreamObject TSO.Close FixBrokenDictionary() Exit Sub End If Else noDict = False For i = LBound(aFields) to UBound(aFields) RE.Pattern = "InfoKey: " & aFields(i,0) If RE.Test(sLine) Then sLine = TSO.ReadLine aFields(i,1) = Mid(sLine, 12) End If Next End If Loop ' Close TextStreamObject TSO.Close End If End Sub Private Sub DisplayMetaData Dim i, msg, tabs, retval msg = "Your PDF file has the following properties:" & vbCRLF & vbCRLF For i = LBound(aFields) to UBound(aFields) If Len(aFields(i,0)) > 7 Then tabs = vbTab Else tabs = vbTab & vbTab msg = msg & aFields(i,0) & ": " & tabs & aFields(i,1) & vbCRLF Next msg = msg & vbCRLF & vbCRLF & "Click OK to continue or Cancel to quit." retval = msgbox (msg, vbOKCancel, sAppTitle ) If retval = vbCancel Then WScript.Quit 1 End Sub Private Sub PromptForMetaData ' Prompt user for metadata, using metadata in original file as defaults Dim i For i = LBound(aFields) to UBound(aFields) aFields(i,1) = _ InputBox("Enter the " & aFields(i,0) & ":", sAppTitle, aFields(i,1)) Next End Sub Private Sub WriteNewMetaData Dim FSO, TSO ' Open a text file and write metadata to it Set FSO = CreateObject("Scripting.FileSystemObject") Set TSO = FSO.OpenTextFile(sMeta, ForWriting, Create) Dim i For i = LBound(aFields) to UBound(aFields) TSO.Write "InfoKey: " & aFields(i,0) & vbCrLf TSO.Write "InfoValue: " & aFields(i,1) & vbCrLf Next ' Close TextStreamObject TSO.Close End Sub Private Sub WriteMetaDataIntoNewPDF Dim oShell ' Create a command shell object and set pdftk command string variable set oShell = WScript.CreateObject("Wscript.Shell") sCmd = """" & sPdftk & """" & " " & """" & sInfile & """" & _ " update_info " & """" & sMeta & """" & " output " & """" _ & sTempFile & """" & " dont_ask" Dim retval ' Run pdftk command and destroy local variables to release memory oShell.run sCmd, HideWindow, True retval = msgbox ( "Look for the output file in the temporary folder" & _ " which will open next." & vbCRLF & "The output file" & _ " will have the same name as the original file.", _ vbOKCancel, sAppTitle ) If retval = vbCancel Then WScript.Quit 1 ' Open explorer to temp folder oShell.run "Explorer " & sTempPath, 1, True End Sub