#!/usr/bin/python import sys import os # This script will take a jana.dot file produced using the janadot plugin # and generate an HTML image map from it with links to Doxygen generated # webpages. You would typically run it like this: # # hd_ana -PPLUGINS=janadot -PAUTOACTIVATE=DPhysicsEvent file.hddm # # janadot2html.py jana.dot # # This will produce a few files, but the ones needed are: # jana_map.html # jana_map.gif # jana_map_big.gif # jana_map_big.pdf # # Copy these to any webserver and they provide a clickable # image map linked back to the Doxygen generated documentation. # #<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> # User configurable stuff # Base URL. All links will include this in their path #URL='http://www.jlab.org/Hall-D/software/HDSoftware_Documentation/' URL='' # Size of image in inches. Inches seems like an odd unit since # the image itself is pixels, but that is what dot uses. image_size='12' # Force links to either always point to the data class, the factory # class, or auto-decide. The auto-decide will choose the factory # class unless the "shape" attribute is "trapezium" which indicates # it came from the event source, not an algorithm. # Valid choices are: 'auto', 'data', or 'factory' link_preference = 'auto' #<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> if (len(sys.argv) > 1): fname = sys.argv[1] print "Processing \""+fname+"\" ..." ifile = open(fname, 'r') lines = ifile.readlines() ofile = open("jana_map.dot", 'w') ofile_big = open("jana_map_big.dot", 'w') for line in lines: pos_bracket_open = line.find('[') pos_bracket_close = line.find(']') pos_arrow = line.find('->') # Look for lines defining objects, but not the connections between objects if (pos_bracket_open>=0 and pos_bracket_close>=0 and pos_arrow==-1): # attributes attributes = line[pos_bracket_open+1:pos_bracket_close] # class name pos_quotes_open = line.find('"') pos_quotes_close = line.find('"',pos_quotes_open+1) class_name = line[pos_quotes_open+1:pos_quotes_close] tmp_class_name = class_name # Decide if we will have the link point to the factory or the data class point_to_factory = 1 #<-+ if(attributes.find('trapezium') > 0): point_to_factory = 0 #<-+ auto if(link_preference == 'factory'): point_to_factory = 1 if(link_preference == 'data'): point_to_factory = 0 # If we are pointing to data class and not the factory class then remove # any ":tag" part of the class name if( not point_to_factory): pos_colon = tmp_class_name.find(':') if(pos_colon>0): tmp_class_name = tmp_class_name[0:pos_colon] # class names starting with "D" assume point to Hall-D defined classes if (tmp_class_name[0]=='D'): # We need to mimic the name mangling Doxygen does to generate the # html file name for the class. Because it uses underscores as an # escape character, we must prepend an underscore to ones that are # part of the actual class name. In addition, any tagged factories # will have a name in the input file with a colon (:) but the actual # class uses an underscore there. doxygen_class_name='' for c in tmp_class_name: if(c == ':'): c = '__factory__' if(c == '_'): doxygen_class_name += '_' doxygen_class_name += c # Doxygen seems to mangle classnames such that capitalized letters # are replaced with lower case letters with a leading underscore. tmp_class_name = doxygen_class_name doxygen_class_name='' for c in tmp_class_name: if(c == c.upper() and c!= '_'): doxygen_class_name += '_'+c.lower() else: doxygen_class_name += c # We want to have the link point to the factory, not the class # itself. (The user can navigate to the data class from the # factory page). If this is a tagged factory, then the colon # has already triggered insertion of "__factory". If not, then # we need to append it to the doxygen class name. if(point_to_factory): if(doxygen_class_name.find('__factory')<0): doxygen_class_name += '__factory' print "found: "+class_name+" converted to: "+doxygen_class_name # Form URL for this box and append it to the attributes class_URL = URL+'class'+doxygen_class_name+'.html' attributes += ',URL="'+class_URL+'"' # Replace the line with one modified to contain the URL attribute line = '"'+class_name+'" ['+attributes+'];\n' ofile.write(line) ofile_big.write(line) # Append some header info after the first line to give a base URL for # areas of the map outside of a box and to set the overall size of the # image if(line.find('digraph G {') >=0): ofile.write('URL="'+URL+'index.html";\n') ofile_big.write('URL="'+URL+'index.html";\n') ofile.write('size='+image_size+';\n') # Close modified dot file ofile.close() ofile_big.close() # Run dot to generate the image and the map using the modified dot file print 'Generating image file and map ...' os.system('dot -Tcmapx -ojana.map -Tgif -ojana_map.gif jana_map.dot') # Run dot again generate full size image files print 'Generating large image files ...' os.system('dot -Tgif -ojana_map_big.gif -Tpdf -ojana_map_big.pdf jana_map_big.dot') # Create html file with image and map info ofile = open("jana_map.html", 'w') ofile.write('\n\n\n
\n\n') # Links to full size images ofile.write('Large Format Images: GIF, PDF\n') # image ofile.write('\n\n\n') # Copy map data into html file ifile = open("jana.map", 'r') lines = ifile.readlines() for line in lines: ofile.write(line) # Close brackets for html and close file ofile.write('\n\n\n\n\n'); ofile.close() print 'All done.' print '\nPlace the files jana_map.html, jana_map.gif, jana_map_big.pdf, and jana_map_big.gif on a webserver.\n' else: print "You must enter a filename!"