forge_fdf in Python

Thursday, April 21 2005 @ 09:29 AM PDT

Contributed by: Admin

Received today from Timothy Stebbing:

gday,

I ported forge_fdf to python for work, I thought it might be useful to you to use/post along with forge_fdf.php on the website for others. I've attached it, it's a direct block-for-block port, it could probably be optimised a fair bit but it was the least amount of effort to port it directly :) It makes an interesting comparison between the languages, just look at the line count ;)

-tjs

This code was later updated by Thomas Heetderks at Frontline Processing:

See the full article for code. Thanks Timothy and Thomas!

Forge_fdf is a little PHP script I created for casting form data into the FDF syntax. This is handy for filling online PDF forms automatically, or for filling forms using pdftk.

Here are some examples of forge_fdf in action:

# This is a port of forge_fdf.php by Sid Steward (www.pdfhacks.com/forge_fdf/)
# Created by Timothy Stebbing  in python.
# Updated by Thomas Heetderks (2006-01-11) and Sid Steward

def escapePDFString(string):
    rv = ''
    for c in string:
        if c in ['(',')','\']:
            rv += '\'+c # escape the character
        elif ord(c) < 32 or 126 < ord(c):
            rv += '\%s3o' % (ord(c),) # use an octal code
        else:
            rv += c # let it pass through
    return rv

def escapePDFName(string):
    rv = ''
    for c in string:
        if ord(c) < 33 or 126 < ord(c) or c == '#':
            rv += '#%s2x' % (ord(c),) # use a hex code
        else:
            rv += c # let it pass through
    return rv

def burstDotsIntoDicts(FDFData):
    rv = {}
    for k, v in FDFData.items():
        if '.' in k:
            lhs, rhs = k.split('.',2)
            if not rv.has_key(lhs):
                rv[lhs] = {}
            if type(rv[lhs]) is dict:
                rv[lhs] = {'' : lhs} #apparently this should not happen
            rv[lhs][rhs] = v
        else:
            if rv.has_key(k) and type(rv[k]) is dict:
                rv[k][''] = v
            else:
                rv[k] = v   
    for k, v in rv.items():
        if type(v) is dict:
            rv[k] = burstDotsIntoDicts(v)
    return rv

def forgeFDFFieldFlags(fdf, fieldName, fieldsHidden, fieldsReadonly):
    if fieldName in fieldsHidden:
        fdf += '/SetF 2' #set
    else:
        fdf += '/ClrF 2' #clear
    if fieldName in fieldsReadonly:
        fdf += '/SetFf 1' #set
    else:
        fdf += '/ClrFf 1' #clear
    return fdf

def forgeFDFFields(fdf, fdfData, fieldsHidden, 
    fieldsReadonly, accumulatedName, fdfDataIsStrings):
    if len(accumulatedName) > 0:
        accumulatedName += '.' #append period seperator
    for k, v in fdfData.items():
        fdf += '> x0d' #close dictionary
    return fdf 

def forgeFDFFieldsStrings(fdf, fdfDataStrings, fieldsHidden, fieldsReadonly):
    return forgeFDFFields(fdf, fdfDataStrings, fieldsHidden, fieldsReadonly,
        '', True)

def forgeFDFFieldsNames(fdf, fdfDataStrings, fieldsHidden, fieldsReadonly):
    return forgeFDFFields(fdf, fdfDataStrings, fieldsHidden, fieldsReadonly,
        '', False)

def forgeFDF(PDFFormURL, FDFDataStrings, 
    FDFDataNames, fieldsHidden, fieldsReadonly):
    fdf = '%FDF-1.2x0d%xe2xe3xcfxd3x0dx0a' #header
    fdf += '1 0 objx0d> x0d' #close the FDF dictionary
    fdf += '>> x0dendobjx0d' #close the root dictionary
    #trailer; note the "1 0 R" reference to "1 0 obj" above
    fdf += 'trailerx0d>x0d'
    fdf += '%%EOFx0dx0a'
    return fdf

14 comments



http://www.accesspdf.com/article.php/20050421092951834