Examples

This section provides some general examples on how to use the priint comet Python API.

Toggle frame visibility

Toggle frame visibility
#!py
import comet

def main():
    visibleBefore = comet.gFrame.getVisible()

    comet.gFrame.setVisible(not visibleBefore)

    visibleNow = comet.gFrame.getVisible()

    comet.showMessage(f'Was visible: {visibleBefore}, is now visible: {visibleNow}')

    return 0

Toggle frame lock state

Toggle frame lock state
#!py
import comet

def main():
    lockedBefore = comet.gFrame.getLocked()

    comet.gFrame.setLocked(not lockedBefore)

    lockedNow = comet.gFrame.getLocked()

    comet.showMessage(f'Was locked: {lockedBefore}, is now locked: {lockedNow}')

    return 0

Show all script tags

Show all script tags of gFrame as a message box
#!py
import comet

def main():
    scriptTags = comet.gFrame.getScriptTags()
    comet.showMessage(str(scriptTags))

    return 0

Reflection

Reflect all comet members and output them to the logfile
#!py
#pragma plain
import inspect
import sys
import comet

def reflect(obj, depth: int = 0):
    #reflect an object by inspecting all attributes and returning a summarizing string
    message = ''

    for name in dir(obj):
        if name.startswith('_'):
            continue
        attr = getattr(obj, name)

        for i in range(depth):
            message += '\t'

        message += '{} - {}\n'.format(name, attr)

        if inspect.isclass(attr) or inspect.ismodule(attr):
            message += reflect(attr, depth + 1)

    return message

def reflectComet():
    #do a full reflection of all comet members and produce a nice formatted output
    message = 'Comet reflection:\n'

    host = comet.host.getType()
    if host == 0:
        message += "Running in InDesign\n"
    if host == 1:
        message += "Running in InDesign Server\n"
    if host == 2:
        message += "Running in comet_pdf\n"
    if host == 3:
        message += "Running in Illustrator\n"

    message += reflect(comet)

    comet.wlog(message)


def main():
    reflectComet()

    return 0

Generate page previews

Generate a JPEG for each page of the front document and save it
#!py
#pragma plain

import os
import comet

def main():
    #Use the front document
    document    = comet.CDocument.getFront()
    if not document:
        return 0

    pages       = document.getPages()

    #Select a target folder to place the previews into:
    #This opens a dialog which prompts the user to select a target folder
    #We suggest the Desktop as the initial folder for the user
    outFolder   = comet.dialog.selectFolder(suggestion = '$DESKTOP')
    if not outFolder:
        #User cancelled - we stop the script
        return 0

    #Export all page previews as JPEG since that is supported on each platform
    for page in pages:
        pageName = page.getName()
        fileName = pageName + '.jpg'
        filePath = os.path.join(outFolder, fileName)

        page.createSnapshot(filePath)

    return 0

Get publication info

Using a priint Pubserver connection, output available publication information
#!py
import comet

def walkPublications(parentID: str = '', recursive: bool = True, depth: int = 0):
    """Recursively walk through all publications and output them to the logfile with proper indentation"""

    #Fetch all publications. When parentID is empty we get the root
    entries = comet.publication.getPublications(parentID)

    for entry in entries:
        name = entry.getValue(comet.constants.kPublicationName)
        hasChildren = entry.getValue(comet.constants.kPublicationHasChildren)

        #depth is only used for indentation in the logfile
        logPrefix = ''
        for i in range(depth):
            logPrefix += '\t'

        comet.wlog(f'{logPrefix}Publication "{name}":')

        #We simply use all available selectors to get all the information we need
        for selector, label in comet.constants.kPublicationSelectors.items():
            value = None
            #We use try/catch here since getValue throws when the selector is invalid
            try:
                value = entry.getValue(selector)
            except:
                continue

            comet.wlog(f'{logPrefix}\tSelector: {label} - Value: {value}')

        if hasChildren and recursive:
            #Recursively walk down
            parentID = entry.getValue(comet.constants.kPublicationStringid)
            walkPublications(parentID, True, depth + 1)

def main():
    walkPublications()

    return 0

Disable all panels

Disable all panels
#!py
import comet

def main():
    for key, value in comet.constants.kPanelIDs.items():
        if key == comet.constants.kPanelUndef:
            continue

        #We need to try/catch since not all panels are available for all hosts.
        #In this case the function throws.
        try:
            comet.prefs.setPanelEnabled(key, False, "I am locked!")
        except:
            pass

    return 0

Get all style names

Get all style names from every style type from the current document and show them as a message
#!py
import comet

def main():
    message = 'All document styles:'

    for styleType, styleTypeName in comet.constants.kStyleTypes.items():
        message += f'\n{styleTypeName}:'

        styles = comet.gDocument.getStyleNames(styleType)

        for style in styles:
            message += f'\n\t{style}'


    comet.showMessage(message)

    return 0

Read Excel file to HTML

Open an excel file and fetch all cell data as HTML
#!py
#pragma plain

import comet
import datetime
import time

def getCellStyle(book: comet.CExcelBook, sheet, column, row):
    #Get the cell style information as HTML by querying cell format
    #attributes and translating them to CSS tags
    openTag = '<span style="'
    closeTag = ''

    fontFamily          = book.getFontFamily(sheet, column, row)
    fontSize            = book.getFontSize(sheet, column, row)
    fontColor           = book.getFontColor(sheet, column, row)
    fontStrikeThrough   = book.getFontStrikeThrough(sheet, column, row)
    fontUnderline       = book.getFontUnderline(sheet, column, row)
    fontPosition        = book.getFontPosition(sheet, column, row)
    fontWeight          = book.getFontWeight(sheet, column, row)
    fontItalic          = book.getFontItalic(sheet, column, row)

    fontColorValues     = fontColor.getValues()

    if fontFamily:
        openTag += f'font-family: {fontFamily};'

    openTag += f'font-size: {fontSize}pt;'
    openTag += f'color: rgb({fontColorValues[0]}, {fontColorValues[1]}, {fontColorValues[2]});'


    if fontStrikeThrough:
        openTag     += 'text-decoration: line-through;'

    if fontUnderline:
        openTag     += 'text-decoration: underline;'

    if fontPosition == 2:
        openTag     += 'vertical-align: super;'

    if fontPosition == 3:
        openTag     += 'vertical-align: sub;'

    if fontWeight >= 700:
        openTag     += '<b>'
        closeTag    += '</b>'

    if fontItalic:
        openTag     += '<i>'
        closeTag    += '</i>'

    openTag     += '>'
    closeTag    += '</span>'

    return [openTag, closeTag]

def main():
    #Open the Excel file
    inFile  = comet.selectFile('Select an Excel file', suggestion = '$DESKTOP')
    if not inFile:
        return 0

    ebook           = comet.CExcelBook.open(inFile)
    sheet           = ''
    firstRow        = ebook.getFirstRow('')
    lastRow         = ebook.getLastRow('')
    firstColumn     = ebook.getFirstColumn('')
    lastColumn      = ebook.getLastColumn('')

    print(f'First row: {firstRow}')
    print(f'Last row: {lastRow}')
    print(f'First column: {firstColumn}')
    print(f'Last column: {lastColumn}')

    #Load some data here
    comet.gFrame.replace('')

    completeData = '%!TT_html_'

    for row in range(firstRow, lastRow):
        for column in range(firstColumn, lastColumn):
            colStr      = comet.CExcelBook.indexToColumn(column)
            cellValue   = f'[{colStr}{row + 1}] : '
            openTag, closeTag = getCellStyle(ebook, sheet, column, row)

            cellValue += openTag

            try:
                value       = ebook.read(sheet, column, row)
                cellType    = ebook.getCellType(sheet, column, row)

                if cellType == comet.excel.kCellTypeDateTime:
                    #datetime value in format YYYYMMDDHHMMSS which we still have to parse for nice output
                    comet.wlog(f'Read cell datetime content [{row + 1}, {colStr}]: {value}')

                    #This is a workaround for a bug in the embedded Python interpreter: only the first call to datetime.strptime ever works
                    tempTime = datetime.datetime.now()

                    try:
                        tempTime = datetime.datetime.strptime(value, '%Y%m%d%H%M%S')
                    except:
                        tempTime = datetime.datetime(*(time.strptime(value, "%Y%m%d%H%M%S")[0:6]))

                    value = tempTime.strftime('%m.%d.%Y, %H:%M:%S')
                else:
                    comet.wlog(f'Read cell content [{row + 1}, {colStr}]: {value}')

                cellValue += str(value)

            except BaseException as e:
                comet.wlog(f'Exception at [{row + 1}, {colStr}]: {str(e)}')

            #Get the cell format
            try:
                formatID    = 0
                formatStr   = ''
                formatID, formatStr = ebook.getCellFormat(sheet, column, row)
                if formatID > 0:
                    cellValue += f' / Format {formatID}'

                if formatStr:
                    cellValue += f' <span class="format">{formatStr}</span>'

            except:
                pass

            try:
                formula = ebook.getCellFormula(sheet, column, row)
                if formula:
                    cellValue += f' <span class="formula">{formula}</span>'

            except:
                pass

            cellValue       += closeTag
            completeData    += cellValue
            completeData    += '<br/>\n'

        completeData += '<br/>\n'


    comet.wlog(completeData)

    comet.gFrame.replace(completeData)

    ebook.close()

    return 0

Get CTextModel style runs

Write information about all paragraph(or character) style runs for the current CTextModel
#!py
#pragma plain

import comet

def echoStyleRuns(paraStyle: bool) -> None:

    tm          = comet.gTextModel
    maxLength   = tm.getLength()
    nextStart   = 0

    while True:
        data = None
        if paraStyle:
            data = tm.getParaStyle(nextStart, True)
        else:
            data = tm.getCharStyle(nextStart, True)

        #data contains name, start, length
        name, start, length = data

        if (length <= 0 or nextStart >= maxLength):
            break

        message = 'Name: {}\nStart: {}\nLength: {}'.format(name, start, length)
        comet.wlog('--------------------------------------------------------------------------------')
        comet.wlog(message)
        nextStart = start + length


def main():
    echoStyleRuns(True)         #echo para style runs
    # echoStyleRuns(False)      #uncomment this line to echo char style runs

    return 0

Get swatch information from document

Fetch information about all swatches in a document and output them to the logfile
#!py
#pragma plain

import comet

def main():
    swatches = comet.color.getSwatches(None)

    for swatch in swatches:
        name        = swatch.getName()
        space       = swatch.getSpace()
        type        = swatch.getType()
        tint        = swatch.getTint()
        isSpot      = swatch.getIsSpot()
        isReserved  = swatch.getIsReserved()
        isLocked    = swatch.getIsLocked()
        colors      = swatch.getColors()

        comet.wlog(f"""Swatch:
    Name: {name}
    Type: {type}
    Space: {space}
    Colors: {colors}
    IsSpot: {isSpot}
    IsReserved: {isReserved}
    IsLocked: {isLocked}
    Tint: {tint}""")

    return 0

Output all sibling book documents to the logfile

Get the path of all sibling documents in the same book and output them to the logfile
#!py

import comet

def main():
    book = comet.gDocument.getBook()

    if book:
        gDocumentPath   = comet.gDocument.getPath()
        documents       = book.getDocuments()

        for docPath in documents:
            if docPath == gDocumentPath:
                continue
            comet.wlog(docPath)
    else:
        comet.wlog('No book found')

    return 0

Parse and traverse an XML tree

Parse a CXMLTree from an XML string and walk through all nodes in preorder fashion, outputting their names to the logfile
#!py

import comet

data = """<data>
    <products>
        <product>
            <id>1</id>
            <productgroup>1</productgroup>
            <label>Orange juice</label>
            <attributes>
                <name>
                    <default>Orange juice</default>
                    <deDE>Orangensaft</deDE>
                    <frFR>Jus d‘orange</frFR>
                </name>
                <ingredients>
                    <default>&lt;b&gt;Ingredients:&lt;/b&gt; Orange juice from concentrate.</default>
                    <deDE>&lt;b&gt;Zutaten:&lt;/b&gt; Orangensaft aus Konzentrat.</deDE>
                    <frFR>&lt;b&gt;Ingrédients:&lt;/b&gt; jus d‘orange à partir de concentré</frFR>
                </ingredients>

                <energy>
                    <default>Energy</default>
                    <deDE>Energie</deDE>
                    <frFR>Énergie</frFR>
                </energy>
            </attributes>
        </product>
    </products>
    <productgroups>
        <productgroup>
            <id>1</id>
            <name>Juice</name>
        </productgroup>
    </productgroups>
</data>"""

def main():
    #Do a stack based iteration through all nodes in the tree
    tree    = comet.xmltree.parse(data)
    stack   = [(tree.getRoot(), 0)]         #store node and depth as entries

    while stack:
        node, depth = stack.pop()
        name        = node.getName()
        children    = node.getChildren()
        while children:
            stack.append((children.pop(), depth + 1))

        comet.wlog('\t' * depth + name)     #use the depth to indent the log message
    return 0

Custom dialog

Create a custom dialog, show it and retrieve the control values.
#!py

import comet

def main():
    if comet.gRun > 1:
        return 0
    dialog = comet.dialog.create()

    dropDownEntries = ['Entry one', 'Entry two', '-', 'Entry three', 'Entry four']

    dialog.setTitle('Dialog Demo')
    dialog.setSize(360, 400)

    dialog.addLabel('label1', 'This is a basic dialog framework demo', 40.0, 20.0, 250.0, 30.0)
    dialog.addCheckBox('cb1', 'This is a checkbox', True, 40.0, 60.0, 200.0, 20.0)
    dialog.addTextField('tf1', 'This is a textfield', 40.0, 90.0, 200.0, 20.0)
    dialog.addLabel('label2', 'This is a floatfield:', 40.0, 120.0, 130.0, 20.0)
    dialog.addFloatField('ff1', 10.5, 160.0, 120.0, 75.0, 20.0)
    dialog.addLabel('label3', 'This is an intfield:', 40.0, 150.0, 130.0, 20.0)
    dialog.addIntField('if1', 333, 160.0, 150.0, 75.0, 20.0)
    dialog.addLabel('label4', 'This is a dropdown:', 40.0, 190.0, 130.0, 20.0)
    dialog.addDropDown('dd1', dropDownEntries, 0, 160.0, 190.0, 125.0, 20.0)
    dialog.addMultilineTextField('mtf1', 'This is a \nmulti-\nline-\ntextfield', 40.0, 230.0, 200.0, 75.0)

    dialog.addDefaultButtons()

    dialog.show()
    comet.showMessage(f'''Dialog results:

Closed by confirm button: {dialog.getConfirmingButton()}
cb1: {dialog.getCheckBoxValue('cb1')}
tf1: {dialog.getTextFieldValue('tf1')}
mtf1: {dialog.getMultiLineTextFieldValue('mtf1')}
ff1: {dialog.getFloatFieldValue('ff1')}
if1: {dialog.getIntFieldValue('if1')}
dd1: {dialog.getDropDownValue('dd1')}
'''
    )

    print(f'Dialog specification:\n{dialog.getSpecification()}')

    return 0