#!/usr/bin/python import pygtk pygtk.require("2.0") # Copyright 1999, Hans Breuer # Gimp-Python - allows the writing of Gimp plugins in Python. # Copyright (C) 1997 James Henstridge # # 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. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from gimpfu import * import gimpenums import os import string import sys import time # The list of scopes to group funtions, extend it if you are # interest in more detailed grouping. scopes = ["Iterator", # the gap stuff "parasite","unit","path","text","procedural_db", "drawable","layer","mask","channel","image", "floating_sel","select", "palette", "pattern","gradient","brush", "file","logo", "plug_in_gap", # more gap stuff "plug_in","perl_fu","python_fu","script_fu"] #partypes lent from pdbbrowse by James Henstridge pars = filter(lambda x: x[:4] == 'PDB_', dir(gimpenums)) partypes = [''] * len(pars) for i in pars: partypes[gimpenums.__dict__[i]] = i[4:] del pars, i def write_head(fname,scope,bcolor,omitFuncTitle=0): "Opens file, writes html head, title, starts body" f = open(fname + ".html", "w") print fname + ".html" f.write ("\n\n") f.write (" The Gimp PDB Doc - " + scope + "\n") f.write ("\n") f.write ("\n\n") f.write ('See also: ') write_link(f, "Main Index", "index") f.write ("; ") write_link(f, "Alphabetic", "alphabetic") f.write ("; ") write_link(f, "Misc", "misc") f.write ("; ") write_link(f, "By Author", "byauthor") f.write ("; ") write_link(f, "By Module", "bymodule") f.write ("; ") write_link(f, "By Menu", "bymenu") f.write ("    External Links: ") f.write (' The Gimp;') f.write (' Gimp User Manual') f.write ("\n") if omitFuncTitle : f.write ("

The Gimp " + scope + "

\n") else : f.write ("

The Gimp " + scope + " functions

\n") return f def write_foot(f): "Writes html footer with Version, Date, ... and closes file" f.write ('
' + '' + '\n') f.write('
' + 'The Gimp ' + str(gimp.version[0]) + '.' + str(gimp.version[1]) + '.' + str(gimp.version[2]) + ' (' + sys.platform + ')' + 'Documentation fresh from PDB' + time.strftime("%X %a %x", time.localtime(time.time())) + '
') f.write('Generated by pdb2doc.py written by ' 'Hans Breuer <Hans@Breuer.org>' '') f.write('
\n') f.write("\n\n") f.close() def write_proto(f,params): "Writes the funtion prototype as html table" f.write("\n") #params is a list of tuples [] for (theType, theVar, theDesc) in params : f.write("") f.write("") f.write("") f.write("") f.write("") f.write("
" + partypes[theType] + "" + theVar + "" + str_html(theDesc) + "
") def write_link(f,name,anchor,anchorsub="",bTD=0): "the link written may be enclosed in TD tags" if bTD : f.write("") if "" == anchorsub : f.write("" + name + "") else: f.write("" + name + "") if bTD : f.write("\n") def write_help(f,sFn,pdbFn,protos): "Writes detailed information about a pdb-function-entry (pdbFn)" f.write("\n\n") f.write("

" + pdbFn.proc_name + "

") if protos : if 0 == pdbFn.nparams : f.write("Input: none
\n") else : f.write("Input:
\n") write_proto(f, pdbFn.params) if 0 == pdbFn.nreturn_vals : f.write("Returns: nothing
\n") else : f.write("Returns:
\n") write_proto(f, pdbFn.return_vals) if "" == pdbFn.proc_help : f.write("blurb repeated: " + str_html(pdbFn.proc_blurb) + "
\n") else : f.write(str_html(pdbFn.proc_help) + "
\n") f.write("" + str_html(pdbFn.proc_copyright) + "; " + str_html(pdbFn.proc_date) + "\n

\n") def str_html(s) : "Convert characters in s to there html equivalent." s = string.replace(s,"&","&") #This one first! s = string.replace(s,"<","<") s = string.replace(s,">",">") s = string.replace(s,'"',""") s = string.replace(s,'ä',"ä") s = string.replace(s,'ö',"ö") s = string.replace(s,'ü',"ü") s = string.replace(s,'©',"©") # ... return s def strip_proc_author(sAuthor) : "Remove whitespaces and mail addresses from pdb[].proc_author entries." return str_html(sAuthor) s = string.strip(sAuthor) while (-1 != string.find(s, "<")) : #Not: del s[string.find(s, "<"):string.find(s, ">")] #Not function buffer cause it's new since Python 1.5.2, but it's not really needed here s = s[:string.find(s, "<")] # s = buffer(s,0,string.find(s, "<")) while (-1 != string.find(s, "(")) : s = s[:string.find(s, "<")] # s = buffer(s,0,string.find(s, "(")) s = string.strip(s) s = str_html(s) return s def write_pdb_alphabetic(f, pdbRefDir) : "write the alphabetic indexed file of all pdb functions" f.write ("") pdbAll = pdbRefDir.keys() pdbAll.sort() for sFn in pdbAll: f.write ("\n") write_link(f,sFn,pdbRefDir[sFn],sFn,1) f.write ("\n\n") f.write ("
" + str_html(pdb[sFn].proc_blurb) + "
") def write_pdb_modules(f, pdbRefDir) : pdbAll = pdb.gimp_plugins_query("") # pdbAll[5] contains the execuable names. Because many plug-ins do implement # more than one function, let's set up a dictionary of their function lists execDict = {} idx = -1 import os.path for sExec in pdbAll[5] : idx = idx + 1 # count entries if sExec == None or len(sExec) == 0 or sExec == "none" : break sExec = os.path.basename(sExec) # remember tuple of (Menu, Function) execT = ( pdbAll[11][idx], str_html(pdbAll[1][idx]) ) if execDict.has_key(sExec) : execDict[sExec].append( execT ) else : execDict[sExec] = [ execT ] # new list sExecKeys = execDict.keys() sExecKeys.sort() f.write("") for sExec in sExecKeys : f.write("\n") f.write("
" + sExec + "") sPrefix = "NOT_to_be_found_as_menu_entry" for execT in execDict[sExec] : sFn = execT[0] sMenu = execT[1] # often multiple functions do have a common prefix in menu, write it only once iPrefixLen = string.rfind(sMenu, sPrefix) if -1 == iPrefixLen : iPrefixLen = string.rfind(sMenu, "/") + 1 sPrefix = sMenu[:iPrefixLen] f.write("" + sPrefix+ " ") else : iPrefixLen = len(sPrefix) write_link(f,sMenu[iPrefixLen:],pdbRefDir[sFn],sFn) f.write(" ") f.write("
") def write_api_proto(f, fn, params): "Writes the funtion prototype as api line" f.write(fn + "(") #params is a list of tuples [] for (theType, theVar, theDesc) in params : f.write(partypes[theType] + theVar + ",") f.write(")\n") # The main plug-in function def python_pdbtodoc(sFilename, bcolor, protos=1, bAlphabetic=1, bAuthors=1, bModules=1, bMenu=1): pdbAll = pdb.query() #used to delete scopes allready done sPath = os.path.dirname(sFilename) + "/" # build the main index file f = write_head(sPath + "index", "pdb documentation index", bcolor, 1) f.write("This documentation covers a total of " + str(len(pdbAll)) + " functions. They are sorted by the following scopes:
") scopesSorted = scopes[:] scopesSorted.sort() f.write("") for s in scopesSorted: if scopesSorted.index(s) % 5 == 0 : f.write("") write_link(f,s,s,"",1) if scopesSorted.index(s) % 5 == 4 : f.write("\n") # possibly need to generate empty fields if len(scopesSorted) % 5 != 0 : f.write('\n') f.write('
') write_link(f,"misc","misc",) f.write(" (not covered above)
\n") f.write('

Additional there is an alphabetic index' ' and an index sorted by authors.') f.write('

To update this documentation yourself, you need' ' Gimp Python' ' written by James Henstridge ' ' and the script ' ' pdb2doc.py' ' by Hans Breuer.') write_foot(f) # the following directory is used to xref function helps pdbRefDir = {} # key=pdb[].proc_name,value=filename (allready written) pdbByAuthor = {} #key=pdb[].proc_author,value=list of functions #now for every scope a single file for s in scopes: f = write_head(sPath + s, s, bcolor) pdbList = pdb.query(s) #there may be overlaps with other scopes pdbList.sort() # write an index for this file f.write("") for sFn in pdbList : f.write("\n") if pdbRefDir.has_key(sFn) : write_link(f,sFn,pdbRefDir[sFn],sFn,1) else : write_link(f,sFn,s,sFn,1) f.write("") f.write("
" + str_html(pdb[sFn].proc_blurb) + "
") for sFn in pdbList : if pdbRefDir.has_key(sFn) : pass # remember another xrefs? else : write_help(f,sFn,pdb[sFn],protos) pdbRefDir[sFn] = s # remember as written # many Author entries are polluted with whitespaces, remove them sAuthor = strip_proc_author(pdb[sFn].proc_author) if pdbByAuthor.has_key(sAuthor) : pdbByAuthor[sAuthor].append(sFn) else : pdbByAuthor[sAuthor] = [sFn] pdbAll.remove(sFn) write_foot(f) # now pdbAll only contains functions not already written; write them to s = "misc" f = write_head(sPath + s, s, bcolor) pdbAll.sort() f.write("") for sFn in pdbAll : f.write("\n") write_link(f,sFn,s,sFn,1) f.write("\n") f.write("
" + str_html(pdb[sFn].proc_blurb) + "
") for sFn in pdbAll : pdbRefDir[sFn] = s #remember as written write_help(f,sFn,pdb[sFn],protos) sAuthor = strip_proc_author(pdb[sFn].proc_author) if pdbByAuthor.has_key(sAuthor) : pdbByAuthor[sAuthor].append(sFn) else : pdbByAuthor[sAuthor] = [sFn] write_foot(f) s = "alphabetic" f = write_head(sPath + s, "alphabetic index", bcolor, 1) if not bAlphabetic : f.write("not generated.") else : write_pdb_alphabetic(f, pdbRefDir) write_foot(f) s = "byauthor" f = write_head(sPath + s, "by Author's", bcolor) if not bAuthors : f.write("not generated") else : pdbAuthors = pdbByAuthor.keys() pdbAuthors.sort() for sAuthor in pdbAuthors : f.write("

" + sAuthor + "

") pdbByAuthor[sAuthor].sort() for sFn in pdbByAuthor[sAuthor] : write_link(f,sFn,pdbRefDir[sFn],sFn) f.write(" ") f.write("\n") write_foot(f) s = "bymodule" f = write_head(sPath + s, "by module", bcolor, 1) if not bModules : f.write("not generated") else : write_pdb_modules(f,pdbRefDir) write_foot(f) s = "bymenu" f = write_head(sPath + s, "by Menu", bcolor) if not bMenu : f.write("not generated") else : f.write ("Currently this lists only contains plug-in menu entries.\n

") menuTuple = pdb.gimp_plugins_query("") menuTree = {} # an empty dictionary #the second tuple item is a list of menu strings idx = -1 for sMenu in menuTuple[1] : iAt = string.rfind(sMenu, "/") sKey = sMenu[:iAt] #sKey = buffer(sMenu, 0, iAt) sItem = sMenu[iAt+1:] #sItem = buffer(sMenu, iAt+1, len(sMenu)) idx = idx + 1 #count entries iAt = string.rfind(sKey, "/") if -1 != iAt : # this removes , entries totally sKeySub = sKey[iAt+1:] # sKeySub = buffer(sKey, iAt+1, len(sKey)) sKey = sKey[:iAt] # sKey = buffer(sKey,0,iAt) if menuTree.has_key(sKey) : if menuTree[sKey].has_key(sKeySub) : menuTree[sKey][sKeySub].append((sItem,menuTuple[11][idx])) else : menuTree[sKey][sKeySub] = [(sItem,menuTuple[11][idx])] else : menuTree[sKey] = {} # new sub dictonary menuTree[sKey][sKeySub] = [(sItem,menuTuple[11][idx])] #start new list menuMain = menuTree.keys() menuMain.sort() for sKey in menuMain : f.write("

" + str_html(str(sKey)) + "

") menuSorted = menuTree[sKey].keys() menuSorted.sort() for sMenu in menuSorted : f.write('\n\n') for sItem in menuTree[sKey][sMenu] : if 0 != menuTree[sKey][sMenu].index(sItem) : f.write("") # start another row f.write("") else : f.write(str_html(pdb[sItem[1]].proc_blurb) + "") f.write("\n") f.write("
' + str_html(str(sMenu)) + ' 
") write_link( f,str_html(str(sItem[0])), pdbRefDir[sItem[1]], sItem[1]) f.write(" ") if (pdb[sItem[1]].proc_blurb == "" or pdb[sItem[1]].proc_blurb[0] == "<") : #script's blurb f.write(str_html(pdb[sItem[1]].proc_help) + "

\n") write_foot(f) # save output path if gimp.parasite_find("pdb2doc-outpath") : gimp.parasite_detach("pdb2doc-outpath") try : gimp.attach_new_parasite("pdb2doc-outpath", PARASITE_PERSISTENT, os.path.dirname(sFilename)) except : print "Warning: The autogeneration of gimpenums.py should be extended!" print "Done." # try to restore the last save path ... def get_my_path() : import os.path sPath = "D:\\data\\hb-web\\gimp\\pdb\\gimp13" if os.path.isdir(sPath) : return sPath return os.environ['HOME'] # short cut, because below does not work !? sDefaultPath = None try : sDefaultPath = gimp.parasite_find("pdb2doc-outpath") except : print "gimp.parasite_find failed!" if sDefaultPath is None : return os.environ['HOME'] else : return str(sDefaultPath) register( "python_fu_pdb2doc", "Creates documentation in html format", "Creates documentation in html format which is always up to date...", "Hans Breuer", "Hans Breuer ", "1999", "/Xtns/Python-Fu/PDB To HTML ...", "", [ (PF_FILE, "path", "Path to store documentation (filename ignored!)", get_my_path() + "/index.html"), (PF_COLOR, "background", "The background color for the pages", (255,255,255)), (PF_TOGGLE, "prototypes", "Include function prototypes (input and output parameters)", 0), (PF_TOGGLE, "alphabetic", "generate an alphabetic index", 1), (PF_TOGGLE, "by_author", "generate an index sorted by authors", 1), (PF_TOGGLE, "by_module", "generate an index sorted by modules", 1), (PF_TOGGLE, "by_menu", "generate an index sorted by menu entries", 1), #(PF_TOGGLE, "write_api", "generate an api file to be used with SciTE", 1), ], [], python_pdbtodoc) main()