├── .gitignore ├── CloseAllDocument.py ├── CloseDocument.py ├── CloseDocumentWithParameter.py ├── CreateDocumentFromPreset.py ├── CreateDocumentPreset.py ├── CreateDocumentPresetsByExample.py ├── CreateGuides.py ├── CreateStyles.py ├── DocumentPreferences.py ├── ExportAsEPS.py ├── ExportEachPageAsPDF.py ├── ExportPDF.py ├── ExportPDFWithOptions.py ├── ExportPageRangeAsEPS.py ├── ExportPageRangeAsPDF.py ├── FindTextReplace.py ├── HelloWorld.py ├── Navigate.py ├── OpenDocument.py ├── README.md ├── api_reference ├── indesign_2020.py ├── indesign_2021.py ├── indesign_CC_2018.py └── indesign_CC_2019.py ├── flask-demo ├── README.md ├── app.py ├── requirements.txt └── templates │ ├── download.html │ └── index.html └── interop assemblies ├── Interop.InDesign.2020.dll ├── Interop.InDesign.cc2018.dll ├── Interop.InDesign.cc2019.dll └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .git 2 | .idea 3 | env 4 | venv 5 | my-test.py 6 | .DS_Store 7 | Readme.txt 8 | 9 | # Default stuff for Github, Python 10 | # Byte-compiled / optimized / DLL files 11 | __pycache__/ 12 | *.py[cod] 13 | 14 | # C extensions 15 | *.so 16 | 17 | # Distribution / packaging 18 | .Python 19 | env/ 20 | build/ 21 | develop-eggs/ 22 | dist/ 23 | downloads/ 24 | eggs/ 25 | .eggs/ 26 | lib/ 27 | lib64/ 28 | parts/ 29 | sdist/ 30 | var/ 31 | *.egg-info/ 32 | .installed.cfg 33 | *.egg 34 | 35 | # PyInstaller 36 | # Usually these files are written by a python script from a template 37 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 38 | *.manifest 39 | *.spec 40 | 41 | # Installer logs 42 | pip-log.txt 43 | pip-delete-this-directory.txt 44 | 45 | # Unit test / coverage reports 46 | htmlcov/ 47 | .tox/ 48 | .coverage 49 | .coverage.* 50 | .cache 51 | nosetests.xml 52 | coverage.xml 53 | *,cover 54 | 55 | # Translations 56 | *.mo 57 | *.pot 58 | 59 | # Django stuff: 60 | *.log 61 | 62 | # Sphinx documentation 63 | docs/_build/ 64 | 65 | # PyBuilder 66 | target/ -------------------------------------------------------------------------------- /CloseAllDocument.py: -------------------------------------------------------------------------------- 1 | """ 2 | CloseAllDocument.py 3 | Closes all open documents without saving. 4 | """ 5 | 6 | import win32com.client 7 | 8 | app = win32com.client.Dispatch('InDesign.Application.CC.2017') 9 | 10 | idNo = 1852776480 11 | for x in range(0, app.Documents.Count): 12 | app.Documents.Item(1).Close(idNo) 13 | -------------------------------------------------------------------------------- /CloseDocument.py: -------------------------------------------------------------------------------- 1 | """ 2 | CloseAllDocument.py 3 | Closes the current document. 4 | """ 5 | 6 | import win32com.client 7 | 8 | app = win32com.client.Dispatch('InDesign.Application.CC.2017') 9 | 10 | if app.Documents.Count is not 0: 11 | app.Documents.Item(1).Close() 12 | else: 13 | print('No documents are open') 14 | -------------------------------------------------------------------------------- /CloseDocumentWithParameter.py: -------------------------------------------------------------------------------- 1 | """ 2 | Use idYes to save the document, or use idNo to close the document without saving 3 | If you use idYes, you'll need to provide a reference to a file to save to in the second 4 | parameter (SavingIn).If the file has not been saved, save it to a specific file path. 5 | """ 6 | 7 | import win32com.client 8 | 9 | app = win32com.client.Dispatch('InDesign.Application.CC.2017') 10 | 11 | idYes = 2036691744 12 | if app.Documents.Count > 0: 13 | myDocument = app.Documents.Item(1) 14 | if not myDocument.Saved: 15 | myFile = r'C:\ServerTestFiles\TestDocument.indd' 16 | myDocument.Close(idYes, myFile) 17 | else: 18 | myDocument.Close(idYes) 19 | -------------------------------------------------------------------------------- /CreateDocumentFromPreset.py: -------------------------------------------------------------------------------- 1 | __author__ = "CrudeRags" 2 | __version__ = "1.0" 3 | 4 | """ 5 | Create a document using a preset 6 | """ 7 | 8 | import win32com.client 9 | 10 | app = win32com.client.Dispatch('InDesign.Application.CC.2019') 11 | my_file = r'C:\ServerTestFiles\TestDocument.indd' 12 | 13 | # See all the available local presets 14 | for preset in app.DocumentPresets: 15 | print(preset.name) 16 | 17 | # Choose one from the above presets. If you want your own preset, see CreateDocumentPreset.py 18 | # Once you create a document preset it will persist. No need to create it every time 19 | doc_preset = app.DocumentPresets.Item("7x9Book") 20 | myDoc = app.Documents.Add(DocumentPreset = doc_preset) 21 | myDoc.Save() 22 | myDoc.Close() 23 | 24 | -------------------------------------------------------------------------------- /CreateDocumentPreset.py: -------------------------------------------------------------------------------- 1 | """ 2 | Creates a new document preset. 3 | If the document preset "7x9Book" does not already exist, create it. 4 | """ 5 | 6 | import win32com.client 7 | 8 | app = win32com.client.Dispatch('InDesign.Application.CC.2017') 9 | 10 | idPortrait = 1751738216 11 | try: 12 | myDocumentPreset = app.DocumentPresets.Item("7x9Book") 13 | presetName = myDocumentPreset.Name 14 | print('preset already exist') 15 | except Exception as e: 16 | print(e) 17 | myDocumentPreset = app.DocumentPresets.Add() 18 | myDocumentPreset.Name = "7x9Book" 19 | 20 | myDocumentPreset.PageHeight = "9i" 21 | myDocumentPreset.PageWidth = "7i" 22 | myDocumentPreset.Left = "4p" 23 | myDocumentPreset.Right = "6p" 24 | myDocumentPreset.Top = "4p" 25 | myDocumentPreset.Bottom = "9p" 26 | myDocumentPreset.ColumnCount = 1 27 | myDocumentPreset.DocumentBleedBottomOffset = "3p" 28 | myDocumentPreset.DocumentBleedTopOffset = "3p" 29 | myDocumentPreset.DocumentBleedInsideOrLeftOffset = "3p" 30 | myDocumentPreset.DocumentBleedOutsideOrRightOffset = "3p" 31 | myDocumentPreset.FacingPages = True 32 | myDocumentPreset.PageOrientation = idPortrait 33 | myDocumentPreset.PagesPerDocument = 1 34 | myDocumentPreset.SlugBottomOffset = "18p" 35 | myDocumentPreset.SlugTopOffset = "3p" 36 | myDocumentPreset.SlugInsideOrLeftOffset = "3p" 37 | myDocumentPreset.SlugRightOrOutsideOffset = "3p" 38 | -------------------------------------------------------------------------------- /CreateDocumentPresetsByExample.py: -------------------------------------------------------------------------------- 1 | """ 2 | Use the DocumentPreferences object to change the 3 | dimensions and orientation of the document 4 | """ 5 | 6 | import win32com.client 7 | 8 | app = win32com.client.Dispatch('InDesign.Application.CC.2017') 9 | 10 | myFile = r'C:\ServerTestFiles\TestDocument.indd' 11 | myDocument = app.Open(myFile) 12 | 13 | myDocumentPrefs = myDocument.DocumentPreferences 14 | 15 | try: 16 | myDocumentPreset = app.DocumentPresets.Item("myDocumentPreset") 17 | presetName = myDocumentPreset.Name 18 | print('preset already exist: ' + presetName) 19 | except Exception as e: 20 | print(e) 21 | myDocumentPreset = app.DocumentPresets.Add() 22 | myDocumentPreset.Name = "myDocumentPreset" 23 | myDocumentPreset.Left = myDocument.MarginPreferences.Left 24 | myDocumentPreset.Right = myDocument.MarginPreferences.Right 25 | myDocumentPreset.Top = myDocument.MarginPreferences.Top 26 | myDocumentPreset.Bottom = myDocument.MarginPreferences.Bottom 27 | myDocumentPreset.ColumnCount = myDocument.MarginPreferences.ColumnCount 28 | myDocumentPreset.ColumnGutter = myDocument.MarginPreferences.ColumnGutter 29 | myDocumentPreset.DocumentBleedBottomOffset = myDocumentPrefs.DocumentBleedBottomOffset 30 | myDocumentPreset.DocumentBleedTopOffset = myDocumentPrefs.DocumentBleedTopOffset 31 | myDocumentPreset.DocumentBleedInsideOrLeftOffset = myDocumentPrefs.DocumentBleedInsideOrLeftOffset 32 | myDocumentPreset.DocumentBleedOutsideOrRightOffset = myDocumentPrefs.DocumentBleedOutsideOrRightOffset 33 | myDocumentPreset.FacingPages = myDocument.DocumentPreferences.FacingPages 34 | myDocumentPreset.PageHeight = myDocument.DocumentPreferences.PageHeight 35 | myDocumentPreset.PageWidth = myDocument.DocumentPreferences.PageWidth 36 | myDocumentPreset.PageOrientation = myDocument.DocumentPreferences.PageOrientation 37 | myDocumentPreset.PagesPerDocument = myDocument.DocumentPreferences.PagesPerDocument 38 | myDocumentPreset.SlugBottomOffset = myDocument.DocumentPreferences.SlugBottomOffset 39 | myDocumentPreset.SlugTopOffset = myDocument.DocumentPreferences.SlugTopOffset 40 | myDocumentPreset.SlugInsideOrLeftOffset = myDocument.DocumentPreferences.SlugInsideOrLeftOffset 41 | myDocumentPreset.SlugRightOrOutsideOffset = myDocument.DocumentPreferences.SlugRightOrOutsideOffset 42 | -------------------------------------------------------------------------------- /CreateGuides.py: -------------------------------------------------------------------------------- 1 | """ 2 | Add a series of guides using the createGuides method 3 | """ 4 | 5 | import win32com.client 6 | 7 | app = win32com.client.Dispatch('InDesign.Application.CC.2017') 8 | 9 | myDocument = app.Documents.Add() 10 | 11 | """ 12 | Parameters (all optional): row count, column count, row gutter, 13 | column gutter,guide color, fit margins, remove existing, layer. 14 | Note that the createGuides method does not take an RGB array 15 | for the guide color parameter. 16 | """ 17 | idGray = 1766290041 18 | myDocument.Spreads.Item(1).CreateGuides(4, 4, "1p", "1p", idGray, True, True, myDocument.Layers.Item(1)) 19 | 20 | # Save the file (fill in a valid file path on your system). 21 | myFile = r'C:\ServerTestFiles\TestDocument.indd' 22 | 23 | myDocument = myDocument.Save(myFile) 24 | myDocument.Close() 25 | -------------------------------------------------------------------------------- /CreateStyles.py: -------------------------------------------------------------------------------- 1 | __author__ = "CrudeRags" 2 | __version__ = "1.0" 3 | 4 | """ 5 | Create Paragraph and Character Styles 6 | """ 7 | 8 | import win32com.client 9 | 10 | app = win32com.client.Dispatch('InDesign.Application.CC.2019') 11 | 12 | try: 13 | # Paragraph Style 1 14 | myParagraphStyle = app.ParagraphStyles.Add() 15 | myParagraphStyle.name = "Tamil Basic Paragraph" 16 | myParagraphStyle.appliedFont = "Tamil Bible" 17 | myParagraphStyle.basedOn = '[No Paragraph Style]' 18 | myParagraphStyle.fontStyle = 'Plain' 19 | myParagraphStyle.paragraphJustification = 1886020709 20 | myParagraphStyle.pointSize = 12.0 21 | except Exception as e: 22 | print(e) 23 | pass 24 | 25 | # Paragraph Style 2 26 | newPStyle = app.ParagraphStyles.Add() 27 | newPStyle.name = "Verse Indent" 28 | newPStyle.appliedFont = 'Tamil Bible' 29 | newPStyle.leftIndent = 2.8 30 | newPStyle.skew = 15.0 31 | 32 | # Paragraph Style 3 33 | titleStyle = app.ParagraphStyles.Add() 34 | titleStyle.name = "Chapter Title" 35 | titleStyle.appliedFont = 'Tamil Bible' 36 | titleStyle.pointSize = 24.0 37 | titleStyle.strokeWeight = 0.20 38 | 39 | howToUse = """ 40 | How to apply style? 41 | 42 | Get the paragraph you want 43 | (see Navigate.py for getting the paragraph) 44 | and use the property `appliedParagraphStyle` 45 | to apply the styles you created 46 | """ 47 | 48 | # Paragraph Style 4 49 | chapterNoStyle = app.ParagraphStyles.Add() 50 | chapterNoStyle.name = "Chapter Number" 51 | chapterNoStyle.appliedFont = 'Times New Roman' 52 | chapterNoStyle.pointSize = 24.0 53 | chapterNoStyle.strokeWeight = 0.20 54 | 55 | 56 | # Character Style 1 57 | englishStyle = app.CharacterStyles.Add() 58 | englishStyle.name = "English" 59 | englishStyle.appliedFont = 'Times New Roman' 60 | englishStyle.pointSize = 12.0 61 | 62 | -------------------------------------------------------------------------------- /DocumentPreferences.py: -------------------------------------------------------------------------------- 1 | """ 2 | Use the DocumentPreferences object to change the 3 | dimensions and orientation of the document 4 | """ 5 | 6 | import win32com.client 7 | 8 | app = win32com.client.Dispatch('InDesign.Application.CC.2017') 9 | 10 | myDocument = app.Documents.Add() 11 | 12 | idLandscape = 2003395685 13 | try: 14 | myDocument.DocumentPreferences.PageHeight = "800pt" 15 | myDocument.DocumentPreferences.PageWidth = "600pt" 16 | myDocument.DocumentPreferences.PageOrientation = idLandscape 17 | myDocument.DocumentPreferences.PagesPerDocument = 16 18 | except Exception as e: 19 | print(e) 20 | 21 | # Save the file (fill in a valid file path on your system). 22 | myFile = r'C:\ServerTestFiles\TestDocument.indd' 23 | 24 | myDocument = myDocument.Save(myFile) 25 | myDocument.Close() 26 | -------------------------------------------------------------------------------- /ExportAsEPS.py: -------------------------------------------------------------------------------- 1 | """ 2 | Use the DocumentPreferences object to change the 3 | dimensions and orientation of the document 4 | """ 5 | 6 | import win32com.client 7 | import os 8 | 9 | app = win32com.client.Dispatch('InDesign.Application.CC.2017') 10 | 11 | myFile = r'C:\ServerTestFiles\TestDocument.indd' 12 | myDocument = app.Open(myFile) 13 | 14 | idEPSType = 1952400720 15 | if app.Documents.Count is not 0: 16 | myExportedEPSFile = r'C:\ServerTestFiles\TestDocument.eps' 17 | directory = os.path.dirname(myExportedEPSFile) 18 | if not os.path.exists(directory): 19 | os.makedirs(directory) 20 | if os.path.exists(directory): 21 | # app.Documents.Item(1).ExportFile(idEPSType, myExportedEPSFile) 22 | myDocument.Export(idEPSType, myExportedEPSFile) 23 | 24 | myDocument.Close() -------------------------------------------------------------------------------- /ExportEachPageAsPDF.py: -------------------------------------------------------------------------------- 1 | """ 2 | Exports each page of an InDesign document as a separate PDF to 3 | a specified folder using the current PDF export settings. 4 | """ 5 | 6 | import win32com.client 7 | import os 8 | 9 | app = win32com.client.Dispatch('InDesign.Application.CC.2017') 10 | 11 | myFile = r'C:\ServerTestFiles\TestDocument.indd' 12 | myDocument = app.Open(myFile) 13 | 14 | idPDFType = 1952403524 15 | if app.Documents.Count is not 0: 16 | directory = os.path.dirname(myFile) 17 | docBaseName = myDocument.Name 18 | for x in range(0, myDocument.Pages.Count): 19 | myPageName = myDocument.Pages.Item(x + 1).Name 20 | # We want to export only one page at the time 21 | app.PDFExportPreferences.PageRange = myPageName 22 | # strip last 5 char(.indd) from docBaseName 23 | myFilePath = directory + "\\" + docBaseName[:-5] + "_" + myPageName + ".pdf" 24 | myDocument.Export(idPDFType, myFilePath) 25 | 26 | myDocument.Close() 27 | -------------------------------------------------------------------------------- /ExportPDF.py: -------------------------------------------------------------------------------- 1 | """ 2 | Exports the current document as PDF. 3 | Assumes you have a document open. 4 | document.exportFile parameters are: 5 | Format: use either the ExportFormat.pdfType constant or the string "Adobe PDF" 6 | To: a file path as a string 7 | Using: PDF export preset (or a string that is the name of a PDF export preset) 8 | The default PDF export preset names are surrounded by square brackets (e.g., "[Screen]"). 9 | """ 10 | 11 | import win32com.client 12 | import os 13 | 14 | app = win32com.client.Dispatch('InDesign.Application.CC.2017') 15 | 16 | myInddFile = r'C:\ServerTestFiles\TestDocument.indd' 17 | myDocument = app.Open(myInddFile) 18 | 19 | myPDFFile = r'C:\ServerTestFiles\TestDocument.pdf' 20 | directory = os.path.dirname(myPDFFile) 21 | 22 | idPDFType = 1952403524 23 | # 1=[High Quality Print], 2=[PDF/X-1a:2001] etc.. 24 | myPDFPreset = app.PDFExportPresets.Item(1) 25 | try: 26 | if not os.path.exists(directory): 27 | os.makedirs(directory) 28 | if os.path.exists(directory): 29 | myDocument.Export(idPDFType, myPDFFile, False, myPDFPreset) 30 | except Exception as e: 31 | print('Export to PDF failed: ' + str(e)) 32 | myDocument.Close() 33 | 34 | -------------------------------------------------------------------------------- /ExportPDFWithOptions.py: -------------------------------------------------------------------------------- 1 | """ 2 | Exports the current document as PDF. 3 | Assumes you have a document open. 4 | document.exportFile parameters are: 5 | Format: use either the ExportFormat.pdfType constant or the string "Adobe PDF" 6 | To: a file path as a string 7 | Using: PDF export preset (or a string that is the name of a PDF export preset) 8 | The default PDF export preset names are surrounded by square brackets (e.g., "[Screen]"). 9 | """ 10 | 11 | import win32com.client 12 | import os 13 | 14 | app = win32com.client.Dispatch('InDesign.Application.CC.2017') 15 | 16 | myInddFile = r'C:\ServerTestFiles\TestDocument.indd' 17 | myDocument = app.Open(myInddFile) 18 | 19 | myPDFFile = r'C:\ServerTestFiles\TestDocument.pdf' 20 | directory = os.path.dirname(myPDFFile) 21 | 22 | # def setattrs(_self, **kwargs): 23 | # for k, v in kwargs.items(): 24 | # setattr(_self, k, v) 25 | # 26 | # pdfExportPreferences = app.PDFExportPreferences 27 | # pdfExportPreferences.setattr(pdfExportPreferences, 28 | # ExportGuidesAndGrids=False, 29 | # ExportLayers=False, 30 | # ExportNonPrintingObjects=False, 31 | # ExportReaderSpreads=False, 32 | # GenerateThumbnails=False 33 | # ) 34 | 35 | try: 36 | if not os.path.exists(directory): 37 | os.makedirs(directory) 38 | if os.path.exists(directory): 39 | try: 40 | pdfExportPreferences = app.PDFExportPreferences 41 | # Basic PDF output options. 42 | idAllPages = 1886547553 43 | idAcrobat6 = 1097020976 44 | pdfExportPreferences.PageRange = idAllPages 45 | pdfExportPreferences.AcrobatCompatibility = idAcrobat6 46 | pdfExportPreferences.ExportGuidesAndGrids = False 47 | pdfExportPreferences.ExportLayers = False 48 | #pdfExportPreferences.ExportNonPrintingObjects = False 49 | pdfExportPreferences.ExportReaderSpreads = False 50 | pdfExportPreferences.GenerateThumbnails = False 51 | try: 52 | pdfExportPreferences.IgnoreSpreadOverrides = False 53 | except Exception as e: 54 | print("IgnoreSpreadOverrides: " + str(e)) 55 | pdfExportPreferences.IncludeBookmarks = True 56 | pdfExportPreferences.IncludeHyperlinks = True 57 | pdfExportPreferences.IncludeICCProfiles = True 58 | pdfExportPreferences.IncludeSlugWithPDF = False 59 | pdfExportPreferences.IncludeStructure = False 60 | #pdfExportPreferences.InteractiveElements = False 61 | """ 62 | Setting subsetFontsBelow to zero disallows font subsetting 63 | set subsetFontsBelow to some other value to use font subsetting. 64 | """ 65 | pdfExportPreferences.SubsetFontsBelow = 0 66 | # Bitmap compression/sampling/quality options 67 | idZip = 2053730371 68 | idEightBit = 1701722210 69 | idNone = 1852796517 70 | pdfExportPreferences.ColorBitmapCompression = idZip 71 | pdfExportPreferences.ColorBitmapQuality = idEightBit 72 | pdfExportPreferences.ColorBitmapSampling = idNone 73 | 74 | # thresholdToCompressColor is not needed in this example 75 | # colorBitmapSamplingDPI is not needed when colorBitmapSampling is set to none 76 | pdfExportPreferences.GrayscaleBitmapCompression = idZip 77 | pdfExportPreferences.GrayscaleBitmapQuality = idEightBit 78 | pdfExportPreferences.GrayscaleBitmapSampling = idNone 79 | 80 | # thresholdToCompressGray is not needed in this example 81 | # grayscaleBitmapSamplingDPI is not needed when grayscaleBitmapSampling is set to none 82 | pdfExportPreferences.MonochromeBitmapCompression = idZip 83 | pdfExportPreferences.MonochromeBitmapSampling = idNone 84 | # thresholdToCompressMonochrome is not needed in this example 85 | # monochromeBitmapSamplingDPI is not needed when monochromeBitmapSampling is set to none 86 | 87 | # Other compression options 88 | idCompressNone = 1131368047 89 | pdfExportPreferences.CompressionType = idCompressNone 90 | pdfExportPreferences.CompressTextAndLineArt = True 91 | pdfExportPreferences.CropImagesToFrames = True 92 | pdfExportPreferences.OptimizePDF = True 93 | 94 | # Printers marks and prepress options. 95 | # Get the bleed amounts from the document's bleed. 96 | bleedBottom = app.Documents.Item(1).DocumentPreferences.DocumentBleedBottomOffset 97 | bleedTop = app.Documents.Item(1).DocumentPreferences.DocumentBleedTopOffset 98 | bleedInside = app.Documents.Item(1).DocumentPreferences.DocumentBleedInsideOrLeftOffset 99 | bleedOutside = app.Documents.Item(1).DocumentPreferences.DocumentBleedOutsideOrRightOffset 100 | # If any bleed area is greater than zero, then export the bleed marks. 101 | if bleedBottom is 0 and bleedTop is 0 and bleedInside is 0 and bleedOutside is 0: 102 | pdfExportPreferences.BleedMarks = True 103 | else: 104 | pdfExportPreferences.BleedMarks = False 105 | 106 | # Default mark type 107 | idDefault = 1147563124 108 | pdfExportPreferences.PDFMarkType = idDefault 109 | idP125pt = 825374064 110 | printerMarkWeight = idP125pt 111 | pdfExportPreferences.RegistrationMarks = True 112 | try: 113 | pdfExportPreferences.SimulateOverprint = False 114 | except Exception as e: 115 | print("SimulateOverprint: " + str(e)) 116 | pdfExportPreferences.UseDocumentBleedWithPDF = True 117 | # Set viewPDF to true to open the PDF in Acrobat or Adobe Reader 118 | pdfExportPreferences.ViewPDF = True 119 | 120 | except Exception as e: 121 | print(e) 122 | # Now do the export 123 | idPDFType = 1952403524 124 | myDocument.Export(idPDFType, myPDFFile) 125 | except Exception as e: 126 | print('Export to PDF failed: ' + str(e)) 127 | myDocument.Close() 128 | -------------------------------------------------------------------------------- /ExportPageRangeAsEPS.py: -------------------------------------------------------------------------------- 1 | """ 2 | Exports a range of pages as EPS files. 3 | Enter the name of the page you want to export in the following line. 4 | Note that the page name is not necessarily the index of the page in the 5 | document (e.g., the first page of a document whose page numbering starts 6 | with page 21 will be "21", not 1). 7 | """ 8 | 9 | import win32com.client 10 | import os 11 | 12 | app = win32com.client.Dispatch('InDesign.Application.CC.2017') 13 | 14 | idEPSType = 1952400720 15 | idPageOrigin = 1380143215 16 | idAutoPageNumber = 1396797550 17 | idCenterAlign = 1667591796 18 | idAscentOffset = 1296135023 19 | 20 | myDocument = app.Documents.Add() 21 | myDocument.ViewPreferences.RulerOrigin = idPageOrigin 22 | myDocument.DocumentPreferences.PagesPerDocument = 12 23 | myMasterSpread = myDocument.MasterSpreads.Item(1) 24 | 25 | def myGetBounds(myDocument, myPage): 26 | myPageWidth = myDocument.DocumentPreferences.PageWidth 27 | myPageHeight = myDocument.DocumentPreferences.PageHeight 28 | myMarginPreferences = myPage.MarginPreferences 29 | myLeft = myMarginPreferences.Left 30 | myTop = myMarginPreferences.Top 31 | myRight = myPageWidth - myMarginPreferences.Right 32 | myBottom = myPageHeight - myMarginPreferences.Bottom 33 | return [myTop, myLeft, myBottom, myRight] 34 | 35 | for x in range(0, myMasterSpread.Pages.Count): 36 | myTextFrame = myMasterSpread.Pages.Item(x + 1).TextFrames.Add() 37 | myTextFrame.Move(None, [1, 1]) 38 | myTextFrame.Contents = idAutoPageNumber 39 | myTextFrame.Paragraphs.Item(1).PointSize = 72 40 | myTextFrame.Paragraphs.Item(1).Justification = idCenterAlign 41 | myTextFrame.TextFramePreferences.FirstBaselineOffset = idAscentOffset 42 | myTextFrame.TextFramePreferences.VerticalJustification = idCenterAlign 43 | myTextFrame.GeometricBounds = myGetBounds(myDocument, myMasterSpread.Pages.Item(x + 1)) 44 | 45 | app.EPSExportPreferences.PageRange = "1-3, 6, 9" 46 | myExportedEPSFile = r'C:\ServerTestFiles\TestDocument.eps' 47 | directory = os.path.dirname(myExportedEPSFile) 48 | 49 | if not os.path.exists(directory): 50 | os.makedirs(directory) 51 | if os.path.exists(directory): 52 | myDocument.Export(idEPSType, myExportedEPSFile) 53 | 54 | -------------------------------------------------------------------------------- /ExportPageRangeAsPDF.py: -------------------------------------------------------------------------------- 1 | """ 2 | Exports a range of pages to a PDF file. 3 | Enter the names of the pages you want to export in the following line. 4 | Note that the page name is not necessarily the index of the page in the 5 | document (e.g., the first page of a document whose page numbering starts 6 | with page 21 will be "21", not 1). 7 | """ 8 | 9 | import win32com.client 10 | import os 11 | 12 | app = win32com.client.Dispatch('InDesign.Application.CC.2017') 13 | 14 | idPDFType = 1952403524 15 | idPageOrigin = 1380143215 16 | idAutoPageNumber = 1396797550 17 | idCenterAlign = 1667591796 18 | idAscentOffset = 1296135023 19 | 20 | myDocument = app.Documents.Add() 21 | myDocument.ViewPreferences.RulerOrigin = idPageOrigin 22 | myDocument.DocumentPreferences.PagesPerDocument = 12 23 | myMasterSpread = myDocument.MasterSpreads.Item(1) 24 | 25 | def myGetBounds(myDocument, myPage): 26 | myPageWidth = myDocument.DocumentPreferences.PageWidth 27 | myPageHeight = myDocument.DocumentPreferences.PageHeight 28 | myMarginPreferences = myPage.MarginPreferences 29 | myLeft = myMarginPreferences.Left 30 | myTop = myMarginPreferences.Top 31 | myRight = myPageWidth - myMarginPreferences.Right 32 | myBottom = myPageHeight - myMarginPreferences.Bottom 33 | return [myTop, myLeft, myBottom, myRight] 34 | 35 | for x in range(0, myMasterSpread.Pages.Count): 36 | myTextFrame = myMasterSpread.Pages.Item(x + 1).TextFrames.Add() 37 | myTextFrame.Move(None, [1, 1]) 38 | myTextFrame.Contents = idAutoPageNumber 39 | myTextFrame.Paragraphs.Item(1).PointSize = 72 40 | myTextFrame.Paragraphs.Item(1).Justification = idCenterAlign 41 | myTextFrame.TextFramePreferences.FirstBaselineOffset = idAscentOffset 42 | myTextFrame.TextFramePreferences.VerticalJustification = idCenterAlign 43 | myTextFrame.GeometricBounds = myGetBounds(myDocument, myMasterSpread.Pages.Item(x + 1)) 44 | 45 | app.PDFExportPreferences.PageRange = "1-3, 6, 9" 46 | myExportedPDFFile = r'C:\ServerTestFiles\TestDocument.pdf' 47 | directory = os.path.dirname(myExportedPDFFile) 48 | 49 | if not os.path.exists(directory): 50 | os.makedirs(directory) 51 | if os.path.exists(directory): 52 | myDocument.Export(idPDFType, myExportedPDFFile) 53 | 54 | -------------------------------------------------------------------------------- /FindTextReplace.py: -------------------------------------------------------------------------------- 1 | from win32com.client import Dispatch 2 | 3 | app = Dispatch("InDesign.Application.CC.2019") 4 | # What to find? 5 | app.FindTextPreferences.FindWhat = 'consequatur' 6 | # Change to what? 7 | app.ChangeTextPreferences.ChangeTo = 'molutem' 8 | 9 | app.ActiveDocument.ChangeText() 10 | # app.Selection[0].ChangeText() 11 | 12 | idNothing = 1851876449 #from enum idNothingEnum, see doc_reference 13 | #reset Preferences 14 | app.FindTextPreferences.FindWhat = idNothing 15 | app.ChangeTextPreferences.ChangeTo = idNothing 16 | -------------------------------------------------------------------------------- /HelloWorld.py: -------------------------------------------------------------------------------- 1 | # HelloWorld.jsx 2 | 3 | import win32com.client 4 | import os 5 | 6 | app = win32com.client.Dispatch('InDesign.Application.CC.2017') 7 | 8 | # Get reference to InDesign application 9 | # app = indesign.Dispatch('InDesign.Application.CC.2017') 10 | # Create a new document. 11 | myDocument = app.Documents.Add() 12 | # Get a reference to the first page. 13 | myPage = myDocument.Pages.Item(1) 14 | # Create a text frame. 15 | myTextFrame = myPage.TextFrames.Add() 16 | # Specify the size and shape of the text frame. 17 | myTextFrame.GeometricBounds = ["6p0", "6p0", "18p0", "18p0"] 18 | # Enter text in the text frame. 19 | myTextFrame.Contents = "Hello World!" 20 | # Save the document (fill in a valid file path). 21 | myFile = r'C:\ServerTestFiles\HelloWorld.indd' 22 | directory = os.path.dirname(myFile) 23 | try: 24 | # If file path does not exist, create directory 25 | if not os.path.exists(directory): 26 | os.makedirs(directory) 27 | # If file path exist, save the file to the path 28 | if os.path.exists(directory): 29 | myDocument.Save(myFile) 30 | except Exception as e: 31 | print('Export to PDF failed: ' + str(e)) 32 | # Close the document. 33 | myDocument.Close() 34 | -------------------------------------------------------------------------------- /Navigate.py: -------------------------------------------------------------------------------- 1 | # NavigateDocument.py 2 | 3 | # Created: 4/17/2020 4 | 5 | __author__ = "CrudeRags" 6 | __version__ = "1.1" 7 | 8 | """ 9 | Navigate a book, and its documents pagewise and storywise 10 | """ 11 | 12 | import win32com.client 13 | import os 14 | 15 | #Use your version of InDesign here 16 | app = win32com.client.Dispatch('InDesign.Application.CC.2019') 17 | idnPath = os.path.abspath(r"path_to_book") 18 | bookPath = os.path.join(idnPath,'book_name.indb') 19 | 20 | # ShowingWindow - option to show/hide what is opened. 21 | app.Open(From = bookPath, ShowingWindow = False) 22 | myBook = app.ActiveBook 23 | 24 | # bookContents property gives access to bookContent object. The specific content has to opened separately 25 | for doc in myBook.bookContents: 26 | doc_name = doc.name 27 | #Open document 28 | myDoc = app.Open(From = doc.fullName, ShowingWindow=False) 29 | #Get first story from document 30 | doc_story = myDoc.Stories[0] 31 | #Navigate a document page wise 32 | for myPage in myDoc.Pages: 33 | #Get the text frames in the page 34 | for myFrame in myPage.TextFrames: 35 | #Get Contents directly: Type = str 36 | myContents = myFrame.Contents 37 | 38 | #Get paragraphs in the text frame 39 | for myPara in myFrame.Paragraphs: 40 | #Get Paragraph style 41 | print(myPara.appliedParagraphStyle) 42 | # if str(myPara.appliedParagraphStyle) == "Basic Paragraph": 43 | # do something 44 | 45 | #Navigate a document storywise 46 | for story in myDoc.Stories: 47 | # print(story.Contents) 48 | 49 | for para in story.Paragraphs: 50 | #do stuff 51 | para.Contents += "Hi there!" 52 | 53 | 54 | #Get all the paragraph styles in the document 55 | 56 | for style in myDoc.ParagraphStyles: 57 | print(style) 58 | -------------------------------------------------------------------------------- /OpenDocument.py: -------------------------------------------------------------------------------- 1 | """ 2 | OpenDocument.py 3 | Opens an existing document. You'll have to fill in your own file path 4 | """ 5 | 6 | import win32com.client 7 | import os 8 | 9 | app = win32com.client.Dispatch('InDesign.Application.CC.2017') 10 | 11 | myFile = r'C:\ServerTestFiles\TestDocument.indd' 12 | directory = os.path.dirname(myFile) 13 | 14 | if not os.path.exists(directory): 15 | os.makedirs(directory) 16 | myDocument = app.Documents.Add() 17 | myDocument = myDocument.Save(myFile) 18 | myDocument.Close() 19 | if os.path.exists(directory): 20 | myDocument = app.Open(myFile) 21 | myPage = myDocument.Pages.Item(1) 22 | myRectangle = myPage.Rectangles.Add() 23 | myRectangle.GeometricBounds = ["6p", "6p", "18p", "18p"] 24 | myRectangle.StrokeWeight = 12 25 | #leave the document open... 26 | print(myDocument.FullName) 27 | # myDocument.Close() 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # InDesign Scripting In Python 2 | ![](https://i.imgur.com/mnmAIDH.png "Logo Title Text 1") 3 | 4 | Scripting in InDesign is used to automate a wide variety of repetative task or as complex as an entire new feature. It is one of the most powerful features in InDesign. It can save lots of time: almost anything you can do with the user interface, you can do with scripts, and there are even a few things you can do in scripting that you cannot do from within the user interface. Scripting is also a good way to do accurate placing and to repeat the same action dozens, hundreds, or thousands of times. If you've never done scripting in InDesign, you should first read the scripting [documentations](https://console.adobe.io/downloads/id) 5 | 6 | # But why Python? 7 | InDesign scripting officially supports JavaScript, AppleScript & VBScript and the Scripting SDK ships with tutorials and guides for each of those supported Scripting language. However, Scripting in Python is also fairly easy if not easier if you're already comfortable with Python. You may have already heard that Python is gaining in popularity, but did you know it’s now the most popular introductory programming language in U.S. universities? Python is also cross platform just like JavaScript is and lately becoming one of the fastest growing programming language according to StackOverflow [as of 2017](https://stackoverflow.blog/2017/09/06/incredible-growth-python) / [as of 2019](https://insights.stackoverflow.com/survey/2019#key-results) 8 | 9 | Python is easy to use, powerful, and versatile, making it a great choice for beginners and experts alike. Python’s readability makes it a great first programming language - it allows you to think like a programmer and not waste time understanding the mysterious syntax that other programming languages can require. 10 | 11 | # InDesign COM & DOM 12 | InDesign can be scripted through COM(Component Object Model). Its DOM(Document Object Model) is the same when accessing it through either its own JavaScript engine or Python or any other scripting language. InDesign exposes it's scripting DOM as a Type Library file at the time of application startup. This is because all the scripting methods available in the DOM is provided by the individual scriptable Plug-Ins. Those Plug-Ins could be the stock Plug-Ins that ships with InDesign or any other third party Plug-Ins which as installed in the Plug-Ins directory. The type library file is written out during application launch at `C:\Users\username\AppData\Local\Adobe\InDesign\\en_US\Caches\Scripting Support\\Resources for Visual Basic.tlb` 13 | 14 | Python allows you to access COM and it's DOM with the help of a Python extension called "Python Win32 Extensions", for more details check https://sourceforge.net/projects/pywin32/ 15 | 16 | However, in order to install this extension, you have to manually download and link to your existing Python installation which can be cumbersome. Instead, there is now a version of pywin32 on PyPI that can be installed with pip. It is called pypiwin32, and it installs the package using the binary wheel format. 17 | 18 | * `pip install pypiwin32` 19 | 20 | Now to call InDesign COM 21 | 22 | ```python 23 | import win32com.client 24 | app = win32com.client.Dispatch('InDesign.Application.CC.2017') 25 | 26 | myDocument = app.Documents.Add() 27 | myPage = myDocument.Pages.Item(1) 28 | myTextFrame = myPage.TextFrames.Add() 29 | myTextFrame.GeometricBounds = ["6p0", "6p0", "18p0", "18p0"] 30 | myTextFrame.Contents = "Hello World!" 31 | ``` 32 | # How to inspect scripting object properties? 33 | There's not a straight forward way, you need to read the documentation to understand what properties/attributes are available for a scripting object, or possibly a COM browser. For example, I've extracted the Python scripting object reference for InDesign CC 2018 at [api_reference](https://github.com/lohriialo/indesign-scripting-python/tree/master/api_reference) 34 | 35 | # More Example 36 | [Here's](https://github.com/lohriialo/indesign-scripting-python/tree/master/flask-demo) another example of how easy it is to setup a web application with Flask in Python. Where, InDesign Server running on a server takes the user inputed data and generate a business cards on the fly. See [`flask-demo`](https://github.com/lohriialo/indesign-scripting-python/tree/master/flask-demo) for the example 37 | 38 | # Scripting on Mac? 39 | Yes, scripting on Mac is also possible, see [photoshop_mac_scripting](https://github.com/lohriialo/photoshop-scripting-python/tree/master/mac_scripting) for more details as a reference to get started 40 | 41 | # Note 42 | Python is not directly supported as a first party scripting language, so you cannot drop a python file in the scripts folder and have InDesign execute it. At the moment, the only way to script is via COM as demonstrated in the examples 43 | 44 | There's a feature request though to add support for Python in InDesign, you might want to go give your vote [here](https://indesign.uservoice.com/forums/601021-adobe-indesign-feature-requests/suggestions/32193772-add-python-to-the-list-of-supported-scripting-lang) 45 | 46 | # InDesign Scripting Resources 47 | * [InDesign API](https://developer.adobe.com/indesign) 48 | * [InDesign Scripting Documentation](https://developer.adobe.com/console/1127/servicesandapis/id) 49 | * [InDesign Scripting Developer Forum](https://community.adobe.com/t5/indesign/ct-p/ct-indesign?page=1&sort=latest_replies&filter=all&lang=all&tabid=discussions&topics=label-scripting%2Clabel-sdk) 50 | * [InDesign Scripting API Reference](https://www.indesignjs.de/extendscriptAPI/indesign-latest/#Application.html) 51 | * [InDesign Developers Prerelease Program](https://www.adobeprerelease.com/beta/D1A76A97-F7DC-4552-DE3C-FF5F211C7492) 52 | 53 | # Also see 54 | * [Photoshop Scripting in Python](https://github.com/lohriialo/photoshop-scripting-python) 55 | * [Illustrator Scripting in Python](https://github.com/lohriialo/illustrator-scripting-python) 56 | 57 | # Contribution 58 | If you've written a useful InDesign Python script and wants to share with the world, please create a new issue with the file as an attachment to the issue. 59 | 60 | When you submit a script, please try to include the following information at the start of your script 61 | ```python 62 | # script_file_name.py 63 | 64 | # Created: 1st January 2019 65 | __author__ = 'Your Name or Original Author Name' 66 | __version__ = '1.0' 67 | 68 | """ 69 | A short description of what the script does 70 | """ 71 | 72 | """ 73 | Instructions on how to use the script, if any 74 | """ 75 | 76 | ``` 77 | * Go to [indesign-scripting-python/issues/new](https://github.com/lohriialo/indesign-scripting-python/issues/new) 78 | * Add title as `Useful Script` 79 | * Drag & drop your .py script file into the description area 80 | * Click `Submit new issue` 81 | -------------------------------------------------------------------------------- /flask-demo/README.md: -------------------------------------------------------------------------------- 1 | # Python web application with InDesignServer 2 | Here's another example of how easy it is to setup a web application with Flask in Python. Where, InDesign Server running on a server takes the user inputed data and generate business cards on the fly 3 | -------------------------------------------------------------------------------- /flask-demo/app.py: -------------------------------------------------------------------------------- 1 | """ 2 | Opens an InDesign Template, iterate text frames by script label and replace text from user input 3 | Exports to PDF 4 | """ 5 | from flask import Flask, render_template, request, redirect, url_for, send_from_directory 6 | import win32com.client 7 | import os 8 | import pythoncom 9 | 10 | app = Flask(__name__) 11 | 12 | businessCardTemplate = r'C:\ServerTestFiles\BusinessCardTemplate.indt' 13 | myBusinessCard = 'myBusinessCard.pdf' 14 | businessCardFullPath = r'C:\ServerTestFiles' + '\\' + myBusinessCard 15 | directory = os.path.dirname(businessCardFullPath) 16 | 17 | @app.route('/', methods=['GET']) 18 | def my_form(): 19 | return render_template("index.html") 20 | 21 | @app.route('/downloadPDF/') 22 | def downloadPDF(filename): 23 | return send_from_directory(directory, filename, as_attachment=False) 24 | 25 | @app.route('/processData', methods=['GET', 'POST']) 26 | def processData(): 27 | """ 28 | Why CoInitialize? See this for details 29 | https://stackoverflow.com/questions/26745617/win32com-client-dispatch-cherrypy-coinitialize-has-not-been-called 30 | """ 31 | pythoncom.CoInitialize() 32 | 33 | indesign = win32com.client.Dispatch('InDesignServer.Application.CC.2017') 34 | myDocument = indesign.Open(businessCardTemplate) 35 | 36 | textFrames = myDocument.TextFrames 37 | 38 | firstName = request.form['firstName'] 39 | lastName = request.form['lastName'] 40 | jobTitle = request.form['title'] 41 | jobEmail = request.form['email'] 42 | for x in range(textFrames.Count): 43 | if textFrames[x].Label == 'first': 44 | textFrames[x].Contents = firstName 45 | if textFrames[x].Label == 'last': 46 | textFrames[x].Contents = lastName 47 | if textFrames[x].Label == 'title': 48 | textFrames[x].Contents = jobTitle 49 | if textFrames[x].Label == 'email': 50 | textFrames[x].Contents = jobEmail 51 | 52 | idPDFType = 1952403524 53 | idNo = 1852776480 54 | try: 55 | if not os.path.exists(directory): 56 | os.makedirs(directory) 57 | if os.path.exists(directory): 58 | myDocument.Export(idPDFType, businessCardFullPath) 59 | myDocument.Close(idNo) 60 | return render_template("download.html", pdf=myBusinessCard) 61 | except Exception as e: 62 | return 'Export to PDF failed: ' + str(e) 63 | 64 | if __name__ == '__main__': 65 | app.run(debug=True) 66 | -------------------------------------------------------------------------------- /flask-demo/requirements.txt: -------------------------------------------------------------------------------- 1 | Flask==1.0 2 | pypiwin32==219 3 | -------------------------------------------------------------------------------- /flask-demo/templates/download.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

{{ pdf }}


9 | 10 | 11 | -------------------------------------------------------------------------------- /flask-demo/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |
9 | First Name:
10 | Last Name:
11 | Designation:
12 | Email:
13 | 14 |
15 | 16 | -------------------------------------------------------------------------------- /interop assemblies/Interop.InDesign.2020.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lohriialo/indesign-scripting-python/623c28f56a8b74cb9fb17239aff9e57926011644/interop assemblies/Interop.InDesign.2020.dll -------------------------------------------------------------------------------- /interop assemblies/Interop.InDesign.cc2018.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lohriialo/indesign-scripting-python/623c28f56a8b74cb9fb17239aff9e57926011644/interop assemblies/Interop.InDesign.cc2018.dll -------------------------------------------------------------------------------- /interop assemblies/Interop.InDesign.cc2019.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lohriialo/indesign-scripting-python/623c28f56a8b74cb9fb17239aff9e57926011644/interop assemblies/Interop.InDesign.cc2019.dll -------------------------------------------------------------------------------- /interop assemblies/README.md: -------------------------------------------------------------------------------- 1 | These Interop DLLs here are provided as examples for scripting in C# For more information on how to generate Interop DLLs, see https://docs.microsoft.com/en-us/dotnet/framework/interop/how-to-generate-interop-assemblies-from-type-libraries 2 | --------------------------------------------------------------------------------