def output_module_html(webpage_path): '''Output an HTML page for each module''' icons_relpath = relpath(cellprofiler.icons.__path__[0]) all_png_icons = glob(os.path.join(icons_relpath, "*.png")) icon_names = [os.path.basename(f)[:-4] for f in all_png_icons] help_text = """ <h2>Help for CellProfiler Modules</a></h2> <ul>\n""" d = {} module_path = webpage_path if not (os.path.exists(module_path) and os.path.isdir(module_path)): try: os.mkdir(module_path) except IOError: raise ValueError("Could not create directory %s" % module_path) for module_name in sorted(get_module_names()): module = instantiate_module(module_name) location = os.path.split( module.create_settings.im_func.func_code.co_filename)[0] if location == cpprefs.get_plugin_directory(): continue if isinstance(module.category, (str,unicode)): module.category = [module.category] for category in module.category: if not d.has_key(category): d[category] = {} d[category][module_name] = module result = module.get_help() if result is None: continue result = result.replace('<body><h1>','<body><h1>Module: ') # Replace refs to icons in memory with the relative path to the image dir (see above) result = re.sub("memory:",os.path.join("images","").encode('string-escape'),result) # Check if a corresponding image exists for the module if module_name in icon_names: # Strip out end html tags so I can add more stuff result = result.replace('</body>','').replace('</html>','') # Include images specific to the module, relative to html files ('images' dir) LOCATION_MODULE_IMAGES = os.path.join('images','%s.png'%(module_name)) result += '\n\n<div><p><img src="%s", width="50%%"></p></div>\n'%LOCATION_MODULE_IMAGES # Now end the help text result += '</body></html>' fd = open(os.path.join(module_path,"%s.html" % module_name), "w") fd.write(result) fd.close() for category in sorted(d.keys()): sub_d = d[category] help_text += "<li><b>%s</b><br><ul>\n"%category for module_name in sorted(sub_d.keys()): help_text += "<li><a href='%s.html'>%s</a></li>\n" % (module_name, module_name) help_text += "</ul></li>\n" help_text += "</ul>\n" return help_text
def test_01_04_instantiate_all(self): '''Instantiate each module and make sure none import wx''' import cellprofiler.modules as M for name in M.get_module_names(): try: M.instantiate_module(name) except: print "Module %s probably imports wx" % name traceback.print_exc()
def search_module_help(text): '''Search the help for a string text - find text in the module help using case-insensitive matching returns an html document of all the module help pages that matched or None if no match found. ''' matching_help = [] for item in MAIN_HELP: matching_help += __search_menu_helper( item, lambda x:__search_fn(x, text)) count = sum([len(x[2]) for x in matching_help]) for module_name in get_module_names(): module = instantiate_module(module_name) location = os.path.split( module.create_settings.im_func.func_code.co_filename)[0] if location == cpprefs.get_plugin_directory(): continue help_text = module.get_help() matches = __search_fn(help_text, text) if len(matches) > 0: matching_help.append((module_name, help_text, matches)) count += len(matches) if len(matching_help) == 0: return None top = """<html style="font-family:arial"> <head><title>%s found</title></head> <body><h1>Matches found</h1><br><ul> """ % ("1 match" if len(matching_help) == 1 else "%d matches" % len(matching_help)) body = "<br>" match_num = 1 prev_link = ( '<a href="#match%d" title="Previous match">' '<img src="memory:previous.png" alt="previous match"></a>') anchor = '<a name="match%d"><u>%s</u></a>' next_link = ('<a href="#match%d" title="Next match">' '<img src="memory:next.png" alt="next match"></a>') for title, help_text, pairs in matching_help: top += """<li><a href="#match%d">%s</a></li>\n""" % ( match_num, title) if help_text.find("<h1>") == -1: body += "<h1>%s</h1>" % title start_match = re.search(r"<\s*body[^>]*?>", help_text, re.IGNORECASE) if start_match is None: start = 0 else: start = start_match.end() end_match = re.search(r"<\\\s*body", help_text, re.IGNORECASE) if end_match is None: end = len(help_text) else: end = end_match.start() for begin_pos, end_pos in pairs: body += help_text[start:begin_pos] if match_num > 1: body += prev_link % (match_num - 1) body += anchor % (match_num, help_text[begin_pos:end_pos]) if match_num != count: body += next_link % (match_num + 1) start = end_pos match_num += 1 body += help_text[start:end] + "<br>" result = "%s</ul><br>\n%s</body></html>" % (top, body) return result
def test_01_01_output_module_html(self): from cellprofiler.modules import get_module_names, instantiate_module M.output_module_html(self.temp_dir) for module_name in sorted(get_module_names()): fd = None try: fd = open(os.path.join(self.temp_dir, module_name + ".html")) except: module = instantiate_module(module_name) location = os.path.split( module.create_settings.im_func.func_code.co_filename)[0] if location == cpprefs.get_plugin_directory(): continue traceback.print_exc() self.assert_("Failed to open %s.html" % module_name) data = fd.read() fd.close() # # Make sure that some nesting rules are obeyed. # tags_we_care_about = ("i", "b", "ul", "ol", "li", "table", "tr", "td", "th", "h1", "h2", "h3", "html", "head", "body") pattern = r"<\s*([a-zA-Z0-9]+).[^>]*>" anti_pattern = r"</\s*([a-zA-Z0-9]+)[^>]*>" d = {} anti_d = {} COUNT = 0 LIST = 1 for tag in tags_we_care_about: for dd in (d, anti_d): dd[tag] = [0, []] for p, dd in ((pattern, d), (anti_pattern, anti_d)): pos = 0 while (True): m = re.search(p, data[pos:]) if m is None: break tag = m.groups()[0].lower() pos = pos + m.start(1) + 1 if dd.has_key(tag): dd[tag][COUNT] += 1 dd[tag][LIST].append(pos) # # Check table nesting rules # T_TABLE = 0 T_ANTI_TABLE = 1 T_TR = 2 T_ANTI_TR = 3 T_TH = 4 T_ANTI_TH = 5 T_TD = 6 T_ANTI_TD = 7 T_UL = 8 T_ANTI_UL = 9 T_OL = 10 T_ANTI_OL = 11 T_LI = 12 T_ANTI_LI = 13 T_I = 14 T_ANTI_I = 15 T_B = 16 T_ANTI_B = 17 tokens = [] for tag, token, anti_token in (('table', T_TABLE, T_ANTI_TABLE), ('tr', T_TR, T_ANTI_TR), ('td', T_TD, T_ANTI_TD), ('th', T_TH, T_ANTI_TH), ('ul', T_UL, T_ANTI_UL), ('ol', T_OL, T_ANTI_OL), ('li', T_LI, T_ANTI_LI), ('i', T_I, T_ANTI_I), ('b', T_B, T_ANTI_B)): tokens += [(pos, token) for pos in d[tag][LIST]] tokens += [(pos, anti_token) for pos in anti_d[tag][LIST]] tokens = sorted(tokens) S_INIT = 0 S_AFTER_TABLE = 1 S_AFTER_TR = 2 S_AFTER_TD = 3 S_AFTER_TH = 4 S_AFTER_OL = 5 S_AFTER_UL = 6 S_AFTER_LI = 7 S_AFTER_I = 8 S_AFTER_B = 9 state_transitions = { S_INIT: { T_TABLE: S_AFTER_TABLE, T_OL: S_AFTER_OL, T_UL: S_AFTER_UL, T_I: S_AFTER_I, T_B: S_AFTER_B }, S_AFTER_TABLE: { T_ANTI_TABLE: S_INIT, T_TR: S_AFTER_TR }, S_AFTER_TR: { T_ANTI_TR: S_INIT, T_TD: S_AFTER_TD, T_TH: S_AFTER_TH }, S_AFTER_TD: { T_TABLE: S_AFTER_TABLE, T_OL: S_AFTER_OL, T_UL: S_AFTER_UL, T_B: S_AFTER_B, T_I: S_AFTER_I, T_ANTI_TD: S_INIT }, S_AFTER_TH: { T_TABLE: S_AFTER_TABLE, T_OL: S_AFTER_OL, T_UL: S_AFTER_UL, T_B: S_AFTER_B, T_I: S_AFTER_I, T_ANTI_TH: S_INIT }, S_AFTER_OL: { T_LI: S_AFTER_LI, T_ANTI_OL: S_INIT }, S_AFTER_UL: { T_LI: S_AFTER_LI, T_ANTI_UL: S_INIT }, S_AFTER_LI: { T_ANTI_LI: S_INIT, T_TABLE: S_AFTER_TABLE, T_OL: S_AFTER_OL, T_UL: S_AFTER_UL, T_B: S_AFTER_B, T_I: S_AFTER_I }, S_AFTER_I: { T_ANTI_I: S_INIT, T_I: S_AFTER_I, # Stupid but legal <i><i>Foo</i></i> T_B: S_AFTER_B, T_TABLE: S_AFTER_TABLE, T_OL: S_AFTER_OL, T_UL: S_AFTER_UL }, S_AFTER_B: { T_ANTI_B: S_INIT, T_B: S_AFTER_B, T_I: S_AFTER_I, T_TABLE: S_AFTER_TABLE, T_OL: S_AFTER_OL, T_UL: S_AFTER_UL } } state = [] for pos, token in tokens: self.assertTrue( len(state) >= 0, "Error in %s near position %d (%s)" % (module_name, pos, data[max(0, pos - 30):max(pos + 30, len(data))])) top_state, start_pos = (S_INIT, 0) if len(state) == 0 else state[-1] self.assertTrue( state_transitions[top_state].has_key(token), "Nesting error in %s near position %d (%s)" % (module_name, pos, data[max(0, pos - 50):pos] + "^^^" + data[pos:min(pos + 50, len(data))])) next_state = state_transitions[top_state][token] if next_state == S_INIT: state.pop() else: state.append((next_state, pos)) if len(state) > 0: self.assertEqual( len(state), 0, "Couldn't find last closing tag in %s. Last tag position = %d (%s)" % (module_name, state[-1][1], data[(state[-1][1] - 30):(state[-1][1] + 30)])) # # Check begin/end tag counts # for tag in tags_we_care_about: if d.has_key(tag): self.assertTrue( anti_d.has_key(tag), "Missing closing </%s> tag in %s" % (tag, module_name)) self.assertEqual( d[tag][COUNT], anti_d[tag][COUNT], "Found %d <%s>, != %d </%s> in %s" % (d[tag][COUNT], tag, anti_d[tag][COUNT], tag, module_name)) else: self.assertFalse( anti_d.has_key(tag), "Missing opening <%s> tag in %s" % (tag, module_name))
def test_01_01_output_module_html(self): from cellprofiler.modules import get_module_names, instantiate_module M.output_module_html(self.temp_dir) for module_name in sorted(get_module_names()): fd = None try: fd = open(os.path.join(self.temp_dir, module_name + ".html")) except: module = instantiate_module(module_name) location = os.path.split( module.create_settings.im_func.func_code.co_filename)[0] if location == cpprefs.get_plugin_directory(): continue traceback.print_exc() self.assert_("Failed to open %s.html" %module_name) data = fd.read() fd.close() # # Make sure that some nesting rules are obeyed. # tags_we_care_about = ("i","b","ul","ol","li","table","tr","td","th", "h1","h2","h3","html","head", "body") pattern = r"<\s*([a-zA-Z0-9]+).[^>]*>" anti_pattern = r"</\s*([a-zA-Z0-9]+)[^>]*>" d = {} anti_d = {} COUNT = 0 LIST = 1 for tag in tags_we_care_about: for dd in (d, anti_d): dd[tag] = [0, []] for p, dd in ((pattern, d), (anti_pattern, anti_d)): pos = 0 while(True): m = re.search(p, data[pos:]) if m is None: break tag = m.groups()[0].lower() pos = pos + m.start(1)+1 if dd.has_key(tag): dd[tag][COUNT] += 1 dd[tag][LIST].append(pos) # # Check table nesting rules # T_TABLE = 0 T_ANTI_TABLE = 1 T_TR = 2 T_ANTI_TR = 3 T_TH = 4 T_ANTI_TH = 5 T_TD = 6 T_ANTI_TD = 7 T_UL = 8 T_ANTI_UL = 9 T_OL = 10 T_ANTI_OL = 11 T_LI = 12 T_ANTI_LI = 13 T_I = 14 T_ANTI_I = 15 T_B = 16 T_ANTI_B = 17 tokens = [] for tag, token, anti_token in ( ('table', T_TABLE, T_ANTI_TABLE), ('tr', T_TR, T_ANTI_TR), ('td', T_TD, T_ANTI_TD), ('th', T_TH, T_ANTI_TH), ('ul', T_UL, T_ANTI_UL), ('ol', T_OL, T_ANTI_OL), ('li', T_LI, T_ANTI_LI), ('i', T_I, T_ANTI_I), ('b', T_B, T_ANTI_B) ): tokens += [(pos, token) for pos in d[tag][LIST]] tokens += [(pos, anti_token) for pos in anti_d[tag][LIST]] tokens = sorted(tokens) S_INIT = 0 S_AFTER_TABLE = 1 S_AFTER_TR = 2 S_AFTER_TD = 3 S_AFTER_TH = 4 S_AFTER_OL = 5 S_AFTER_UL = 6 S_AFTER_LI = 7 S_AFTER_I = 8 S_AFTER_B = 9 state_transitions = { S_INIT: { T_TABLE: S_AFTER_TABLE, T_OL: S_AFTER_OL, T_UL: S_AFTER_UL, T_I: S_AFTER_I, T_B: S_AFTER_B }, S_AFTER_TABLE: { T_ANTI_TABLE: S_INIT, T_TR: S_AFTER_TR }, S_AFTER_TR: { T_ANTI_TR: S_INIT, T_TD: S_AFTER_TD, T_TH: S_AFTER_TH }, S_AFTER_TD: { T_TABLE: S_AFTER_TABLE, T_OL: S_AFTER_OL, T_UL: S_AFTER_UL, T_B: S_AFTER_B, T_I: S_AFTER_I, T_ANTI_TD: S_INIT }, S_AFTER_TH: { T_TABLE: S_AFTER_TABLE, T_OL: S_AFTER_OL, T_UL: S_AFTER_UL, T_B: S_AFTER_B, T_I: S_AFTER_I, T_ANTI_TH: S_INIT }, S_AFTER_OL: { T_LI: S_AFTER_LI, T_ANTI_OL: S_INIT }, S_AFTER_UL: { T_LI: S_AFTER_LI, T_ANTI_UL: S_INIT }, S_AFTER_LI: { T_ANTI_LI: S_INIT, T_TABLE: S_AFTER_TABLE, T_OL: S_AFTER_OL, T_UL: S_AFTER_UL, T_B: S_AFTER_B, T_I: S_AFTER_I }, S_AFTER_I: { T_ANTI_I: S_INIT, T_I: S_AFTER_I, # Stupid but legal <i><i>Foo</i></i> T_B: S_AFTER_B, T_TABLE: S_AFTER_TABLE, T_OL: S_AFTER_OL, T_UL: S_AFTER_UL }, S_AFTER_B: { T_ANTI_B: S_INIT, T_B: S_AFTER_B, T_I: S_AFTER_I, T_TABLE: S_AFTER_TABLE, T_OL: S_AFTER_OL, T_UL: S_AFTER_UL } } state = [] for pos, token in tokens: self.assertTrue( len(state) >= 0, "Error in %s near position %d (%s)" % (module_name, pos, data[max(0,pos - 30): max(pos + 30, len(data))]) ) top_state, start_pos = (S_INIT,0) if len(state) == 0 else state[-1] self.assertTrue( state_transitions[top_state].has_key(token), "Nesting error in %s near position %d (%s)" % (module_name, pos, data[max(0,pos - 50):pos]+"^^^"+ data[pos:min(pos + 50, len(data))])) next_state = state_transitions[top_state][token] if next_state == S_INIT: state.pop() else: state.append((next_state, pos)) if len(state) > 0: self.assertEqual( len(state), 0, "Couldn't find last closing tag in %s. Last tag position = %d (%s)" % (module_name, state[-1][1], data[(state[-1][1] - 30): (state[-1][1] + 30)])) # # Check begin/end tag counts # for tag in tags_we_care_about: if d.has_key(tag): self.assertTrue(anti_d.has_key(tag), "Missing closing </%s> tag in %s" % (tag, module_name)) self.assertEqual( d[tag][COUNT], anti_d[tag][COUNT], "Found %d <%s>, != %d </%s> in %s" % (d[tag][COUNT], tag, anti_d[tag][COUNT], tag, module_name)) else: self.assertFalse(anti_d.has_key(tag), "Missing opening <%s> tag in %s" % (tag, module_name))