def analyzer_widget_callback(page, elem, uid): """Handles embedding suitable code into the page in order to display and run the analyzer""" vlam = elem.attrib["title"] log_id = extract_log_id(vlam) if log_id: t = "analyzer" config[page.username]["logging_uids"][uid] = (log_id, t) elem.attrib["title"] = "python" analyzercode, show_vlam = plugin["services"].style(page, elem, None, vlam) elem.attrib["title"] = vlam if log_id: config["log"][log_id] = [tostring(markup)] wrap_in_div(elem, uid, vlam, "analyzer", show_vlam) # insert_markup(elem, uid, vlam, markup, "analyzer") # call the insert_editor_subwidget service to insert an editor: plugin["services"].insert_editor_subwidget(page, elem, uid, analyzercode) # some spacing: SubElement(elem, "br") # use the insert_analyzer_button service as any plugin can do insert_analyzer_button(page, elem, uid) SubElement(elem, "br") # finally, an output subwidget: plugin["services"].insert_io_subwidget(page, elem, uid)
def pygments_style(page, elem, dummy_uid='42', vlam=None): cssclass = config[page.username]['style'] wrap = False if vlam is not None: show_vlam = create_show_vlam(page, elem, vlam) elif 'show_vlam' in elem.attrib['title']: show_vlam = create_show_vlam(page, elem, elem.attrib['title']) wrap = True else: show_vlam = None language = elem.attrib['title'].split()[0] if language in ['py_code', 'python_code']: language = "python" text = extract_code(elem) styled_code = _style(text, language, cssclass) if vlam is None: vlam = elem.attrib['title'] if 'linenumber' in vlam: styled_code = add_linenumber(styled_code, vlam) markup = fromstring(styled_code) elem[:] = markup[:] elem.text = markup.text if 'class' in elem.attrib: elem.attrib['class'] += " " + CRUNCHY_PYGMENTS else: elem.attrib['class'] = CRUNCHY_PYGMENTS if not page.includes("pygment_cssclass"): # replacing class name for security reasons. page.add_css_code(HtmlFormatter(style=cssclass).get_style_defs("."+cssclass).replace(cssclass, CRUNCHY_PYGMENTS)) page.add_include("pygment_cssclass") if wrap: wrap_in_div(elem, dummy_uid, '', "show_vlam", show_vlam) return text, show_vlam
def analyzer_widget_callback(page, elem, uid): """Handles embedding suitable code into the page in order to display and run the analyzer""" vlam = elem.attrib["title"] log_id = extract_log_id(vlam) if log_id: t = 'analyzer' config[page.username]['logging_uids'][uid] = (log_id, t) elem.attrib['title'] = "python" analyzercode, show_vlam = plugin['services'].style(page, elem, None, vlam) elem.attrib['title'] = vlam if log_id: config['log'][log_id] = [tostring(markup)] wrap_in_div(elem, uid, vlam, "analyzer", show_vlam) #insert_markup(elem, uid, vlam, markup, "analyzer") # call the insert_editor_subwidget service to insert an editor: plugin['services'].insert_editor_subwidget(page, elem, uid, analyzercode) #some spacing: SubElement(elem, "br") # use the insert_analyzer_button service as any plugin can do insert_analyzer_button(page, elem, uid) SubElement(elem, "br") # finally, an output subwidget: plugin['services'].insert_io_subwidget(page, elem, uid)
def hidden_code_widget_callback(page, elem, uid): """Handles embedding suitable code into the page in order to display and run code samples""" vlam = elem.attrib["title"] config["extracted_lines"][uid] = [] # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, to make # thus making the source easier to read. if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("hidden_code_included"): page.add_include("hidden_code_included") page.add_js_code(hidden_code_jscode) elem.attrib['title'] = "py" complete_code, show_vlam = plugin['services'].style(page, elem, None, vlam) # _lines = complete_code.split('\n') displayed_lines = [] hidden_lines = [] hide = False for _line in _lines: if hide: if _line.strip() == HIDDEN_CODE_END: hide = False config["extracted_lines"][uid].append('\n'.join(hidden_lines)) else: hidden_lines.append(_line) else: if _line.strip() == HIDDEN_CODE_BEGIN: hide = True hidden_lines = [] displayed_lines.append(HIDDEN_CODE_MARKER) else: displayed_lines.append(_line) complete_code = '\n'.join(displayed_lines) elem.attrib['title'] = vlam elem.attrib["class"] += " hidden" elem.attrib["id"] = "hidden_pre_" + uid wrap_in_div(elem, uid, vlam, "hidden_code", show_vlam) btn = SubElement(elem, "button") btn.text = _("Show/hide complete code") btn.attrib["onclick"] = "$('#%s').toggle()" % ("hidden_pre_" + uid) plugin['services'].insert_editor_subwidget(page, elem, uid, complete_code) SubElement(elem, "br") btn = SubElement(elem, "button") btn.attrib["id"] = "run_code_btn_" + uid btn.text = _("Run Code") btn.attrib["onclick"] = "exec_hidden_code('%s')" % uid SubElement(elem, "br") plugin['services'].insert_io_subwidget(page, elem, uid)
def unittest_widget_callback(page, elem, uid): """Handles embedding suitable code into the page in order to display and run unittests""" vlam = elem.attrib["title"] log_id = extract_log_id(vlam) if log_id: t = 'unittest' config[page.username]['logging_uids'][uid] = (log_id, t) # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, to make # thus making the source easier to read. if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("unittest_included"): page.add_include("unittest_included") page.add_js_code(unittest_jscode) elem.attrib['title'] = "python" unittestcode, show_vlam = plugin['services'].style(page, elem, None, vlam) elem.attrib['title'] = vlam if log_id: config['log'][log_id] = [tostring(markup)] # which we store unittests[uid] = unittestcode wrap_in_div(elem, uid, vlam, "doctest", show_vlam) if config[page.username]['popups']: # insert popup helper img = Element("img", src="/images/help.png", style="height:32px;", title="cluetip Hello %s! " % page.username + "This is a unittest.; click for more.", rel="/docs/popups/unittest.html") elem.append(img) plugin['services'].insert_cluetip(page, img, uid) #insert_markup(elem, uid, vlam, markup, "unittest") # call the insert_editor_subwidget service to insert an editor: plugin['services'].insert_editor_subwidget(page, elem, uid) #some spacing: SubElement(elem, "br") # the actual button used for code execution: btn = SubElement(elem, "button") btn.text = "Run Unittest" btn.attrib["onclick"] = "exec_unittest('%s')" % uid if "analyzer_score" in vlam: plugin['services'].add_scoring(page, btn, uid) if "analyzer_report" in vlam: plugin['services'].insert_analyzer_button(page, elem, uid) SubElement(elem, "br") # finally, an output subwidget: plugin['services'].insert_io_subwidget(page, elem, uid)
def insert_interpreter(page, elem, uid): """inserts an interpreter (and the js code to initialise an interpreter)""" vlam = elem.attrib["title"] interp_kind = select_type(vlam, config[page.username]["override_default_interpreter"], elem) # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, to make # thus making the source easier to read. show = True if not ("display" in config[page.username]["page_security_level"](page.url) or interp_kind == None): include_interpreter(interp_kind, page, uid) log_id = util.extract_log_id(vlam) if log_id: t = "interpreter" config[page.username]["logging_uids"][uid] = (log_id, t) else: log_id = False show = False # then we can go ahead and add html markup, extracting the Python # code to be executed in the process - we will not need this code; # this could change in a future version where we could add a button to # have the code automatically "injected" and executed by the # interpreter, thus saving some typing by the user. python_code = util.extract_code(elem) if util.is_interpreter_session(python_code): elem.attrib["title"] = "pycon" python_code = util.extract_code_from_interpreter(python_code) else: elem.attrib["title"] = "python" dummy, show_vlam = plugin["services"].style(page, elem, None, vlam) elem.attrib["title"] = vlam if log_id: config[page.username]["log"][log_id] = [tostring(elem)] util.wrap_in_div(elem, uid, vlam, "interpreter", show_vlam) if config[page.username]["popups"] and interp_kind is not None and not page.includes("interpreter_helper"): page.add_include("interpreter_helper") # insert popup helper img = Element( "img", src="/images/help.png", style="height:32px;", title="cluetip Hello %s! " % page.username + titles[interp_kind], rel=help_files[interp_kind], ) elem.append(img) plugin["services"].insert_cluetip(page, img, uid) plugin["services"].insert_io_subwidget(page, elem, uid, interp_kind=interp_kind, sample_code=python_code, show=show) plugin["services"].insert_tooltip(page, elem, uid) return
def unittest_widget_callback(page, elem, uid): """Handles embedding suitable code into the page in order to display and run unittests""" vlam = elem.attrib["title"] log_id = extract_log_id(vlam) if log_id: t = 'unittest' config[page.username]['logging_uids'][uid] = (log_id, t) # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, to make # thus making the source easier to read. if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("unittest_included") : page.add_include("unittest_included") page.add_js_code(unittest_jscode) elem.attrib['title'] = "python" unittestcode, show_vlam = plugin['services'].style(page, elem, None, vlam) elem.attrib['title'] = vlam if log_id: config['log'][log_id] = [tostring(markup)] # which we store unittests[uid] = unittestcode wrap_in_div(elem, uid, vlam, "doctest", show_vlam) if config[page.username]['popups']: # insert popup helper img = Element("img", src="/images/help.png", style="height:32px;", title = "cluetip Hello %s! "%page.username + "This is a unittest.; click for more.", rel = "/docs/popups/unittest.html") elem.append(img) plugin['services'].insert_cluetip(page, img, uid) #insert_markup(elem, uid, vlam, markup, "unittest") # call the insert_editor_subwidget service to insert an editor: plugin['services'].insert_editor_subwidget(page, elem, uid) #some spacing: SubElement(elem, "br") # the actual button used for code execution: btn = SubElement(elem, "button") btn.text = "Run Unittest" btn.attrib["onclick"] = "exec_unittest('%s')" % uid if "analyzer_score" in vlam: plugin['services'].add_scoring(page, btn, uid) if "analyzer_report" in vlam: plugin['services'].insert_analyzer_button(page, elem, uid) SubElement(elem, "br") # finally, an output subwidget: plugin['services'].insert_io_subwidget(page, elem, uid)
def insert_bare_editor(page, elem, uid): """inserts a 'bare' editor, python code, but no execution buttons. Common code to both insert_editor() and insert_alternate_python(). """ vlam = elem.attrib["title"] log_id = util.extract_log_id(vlam) if log_id: t = 'editor' config[page.username]['logging_uids'][uid] = (log_id, t) # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, # thus making the source easier to read. if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("exec_included"): page.add_include("exec_included") page.add_js_code(exec_jscode) # then we can go ahead and add html markup, extracting the Python # code to be executed in the process python_code = util.extract_code(elem) if util.is_interpreter_session(python_code): elem.attrib['title'] = "pycon" python_code = util.extract_code_from_interpreter(python_code) else: elem.attrib['title'] = "python" dummy, show_vlam = plugin['services'].style(page, elem, None, vlam) elem.attrib['title'] = vlam if log_id: config[page.username]['log'][log_id] = [tostring(elem)] util.wrap_in_div(elem, uid, vlam, "editor", show_vlam) if config[page.username]['popups']: # insert popup helper img = Element("img", src="/images/help.png", style="height:32px;", title="cluetip Hello %s! " % page.username + "This is an Editor; click for more", rel="/docs/popups/editor.html") elem.append(img) plugin['services'].insert_cluetip(page, img, uid) if (("no_copy" in vlam) and not ("no_pre" in vlam)) or (not python_code): python_code = "\n" plugin['services'].insert_editor_subwidget(page, elem, uid, python_code) return vlam
def insert_bare_editor(page, elem, uid): """inserts a 'bare' editor, python code, but no execution buttons. Common code to both insert_editor() and insert_alternate_python(). """ vlam = elem.attrib["title"] log_id = util.extract_log_id(vlam) if log_id: t = 'editor' config[page.username]['logging_uids'][uid] = (log_id, t) # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, # thus making the source easier to read. if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("exec_included"): page.add_include("exec_included") page.add_js_code(exec_jscode) # then we can go ahead and add html markup, extracting the Python # code to be executed in the process python_code = util.extract_code(elem) if util.is_interpreter_session(python_code): elem.attrib['title'] = "pycon" python_code = util.extract_code_from_interpreter(python_code) else: elem.attrib['title'] = "python" dummy, show_vlam = plugin['services'].style(page, elem, None, vlam) elem.attrib['title'] = vlam if log_id: config[page.username]['log'][log_id] = [tostring(elem)] util.wrap_in_div(elem, uid, vlam, "editor", show_vlam) if config[page.username]['popups']: # insert popup helper img = Element("img", src="/images/help.png", style="height:32px;", title = "cluetip Hello %s! "%page.username + "This is an Editor; click for more", rel = "/docs/popups/editor.html") elem.append(img) plugin['services'].insert_cluetip(page, img, uid) if (("no_copy" in vlam) and not ("no_pre" in vlam)) or (not python_code): python_code = "\n" plugin['services'].insert_editor_subwidget(page, elem, uid, python_code) return vlam
def pygments_style(page, elem, dummy_uid='42', vlam=None): cssclass = config[page.username]['style'] wrap = False if vlam is not None: show_vlam = create_show_vlam(page, elem, vlam) elif 'show_vlam' in elem.attrib['title']: show_vlam = create_show_vlam(page, elem, elem.attrib['title']) wrap = True else: show_vlam = None language = elem.attrib['title'].split()[0] if language in ['py_code', 'python_code']: language = "python" text = extract_code(elem) styled_code = _style(text, language, cssclass) if vlam is None: vlam = elem.attrib['title'] if 'linenumber' in vlam: styled_code = add_linenumber(styled_code, vlam) markup = fromstring(styled_code) elem[:] = markup[:] elem.text = markup.text if 'class' in elem.attrib: elem.attrib['class'] += " " + CRUNCHY_PYGMENTS else: elem.attrib['class'] = CRUNCHY_PYGMENTS if not page.includes("pygment_cssclass"): # replacing class name for security reasons. page.add_css_code( HtmlFormatter(style=cssclass).get_style_defs("." + cssclass).replace( cssclass, CRUNCHY_PYGMENTS)) page.add_include("pygment_cssclass") if wrap: wrap_in_div(elem, dummy_uid, '', "show_vlam", show_vlam) return text, show_vlam
def pdb_widget_callback(page, elem, uid): """Handles embedding suitable code into the page in order to display and run pdb""" # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, to make # thus making the source easier to read. if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("pdb_included"): page.add_include("pdb_included") #element tree always escape < to < and break my js code , so... page.insert_js_file("/pdb_js%s.js"%plugin['session_random_id']) if not page.includes("pdb_css_code"): page.add_include("pdb_css_code") page.add_css_code(pdb_css) # next, we style the code, also extracting it in a useful form ... vlam = elem.attrib["title"] python_code = util.extract_code(elem) if util.is_interpreter_session(python_code): elem.attrib['title'] = "pycon" python_code = util.extract_code_from_interpreter(python_code) else: elem.attrib['title'] = "python" code, show_vlam = plugin['services'].style(page, elem, None, vlam) elem.attrib['title'] = vlam util.wrap_in_div(elem, uid, vlam, "pdb", show_vlam) plugin['services'].insert_editor_subwidget(page, elem, uid, python_code) t = SubElement(elem, "h4", style="background-color:white;color:darkblue;") t.text = _("Local Namespace") local_ns_div = SubElement(elem, "div") local_ns_div.attrib["id"] = "local_ns_%s"%uid #some spacing: SubElement(elem, "br") btn = SubElement(elem, "button") btn.text = _("Start PDB") btn.attrib["onclick"] = "init_pdb('%s');" %(uid) btn.attrib["id"] = "btn_start_pdb_%s" % uid btn = SubElement(elem, "button") btn.text = _("Next Step") btn.attrib["id"] = "btn_next_step_%s" % uid btn.attrib["disabled"] = "disabled" btn = SubElement(elem, "button") btn.text = _("Step Into") btn.attrib["id"] = "btn_step_into_%s" % uid btn.attrib["disabled"] = "disabled" btn = SubElement(elem, "button") btn.text = _("Return") btn.attrib["id"] = "btn_return_%s" % uid btn.attrib["disabled"] = "disabled" btn = SubElement(elem, "button") btn.text = _("Next Multiple Steps") btn.attrib["id"] = "btn_next_many_steps_%s" % uid btn.attrib["disabled"] = "disabled" input1 = SubElement(elem, 'input', id='input_many_'+uid, size='4', value='1') t = SubElement(elem, "h4", style="background-color:white;color:darkblue;") t.text = _("Output") # finally, an output subwidget: plugin['services'].insert_io_subwidget(page, elem, uid) #register before_ouput hook plugin['services'].register_io_hook('before_output', pdb_filter, uid) #create pdb file cache for uid pdb_py_files[uid] = {}
def doctest_widget_callback(page, elem, uid): """Handles embedding suitable code into the page in order to display and run doctests""" vlam = elem.attrib["title"] log_id = extract_log_id(vlam) vlam_info = parse_vlam(vlam) limit_time = vlam_info.get("time", None) exam_name = vlam_info.get("exam_name", None) # We check to see if an exam name has been defined (in exam_mode.py). # This is only defined when a test has started. if exam_name: if page.username not in exams: elem.clear() return elif exam_name not in exams[page.username]: elem.clear() return else: exams[page.username][exam_name]['problems'].append(uid) if log_id: t = 'doctest' config[page.username]['logging_uids'][uid] = (log_id, t) # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, to make # thus making the source easier to read. if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("doctest_included") : page.add_include("doctest_included") page.add_js_code(doctest_jscode) # next, we style the code, also extracting it in a useful form ... elem.attrib['title'] = "pycon" doctestcode, show_vlam = plugin['services'].style(page, elem, None, vlam) # remove trailing white spaces, which may mess the expected output... doctestcode_lines = doctestcode.split('\n') for i in range(len(doctestcode_lines)): doctestcode_lines[i] = doctestcode_lines[i].rstrip() doctestcode = '\n'.join(doctestcode_lines) elem.attrib['title'] = vlam if log_id: config[page.username]['log'][log_id] = [tostring(elem)] # which we store doctests[uid] = doctestcode wrap_in_div(elem, uid, vlam, "doctest", show_vlam) if config[page.username]['popups']: # insert popup helper img = Element("img", src="/images/help.png", style="height:32px;", title = "cluetip Hello %s! "%page.username + "This is a doctest.; click for more", rel = "/docs/popups/doctest.html") elem.append(img) plugin['services'].insert_cluetip(page, img, uid) # call the insert_editor_subwidget service to insert an editor: plugin['services'].insert_editor_subwidget(page, elem, uid) #some spacing: SubElement(elem, "br") # the actual button used for code execution: btn = SubElement(elem, "button") btn.attrib["id"] = "run_doctest_btn_" + uid btn.text = _("Run Doctest") btn.attrib["onclick"] = "exec_doctest('%s')" % uid if "analyzer_score" in vlam: plugin['services'].add_scoring(page, btn, uid) if "analyzer_report" in vlam: plugin['services'].insert_analyzer_button(page, elem, uid) SubElement(elem, "br") if limit_time: page.add_js_code("window.addEventListener('load', function(e){count_down('%s', get_doctest_time('%s'));}, false);" %(uid, uid)) # finally, an output subwidget: plugin['services'].insert_io_subwidget(page, elem, uid)
def insert_interpreter(page, elem, uid): """inserts an interpreter (and the js code to initialise an interpreter)""" vlam = elem.attrib["title"] interp_kind = select_type( vlam, config[page.username]['override_default_interpreter'], elem) # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, to make # thus making the source easier to read. show = True if not ('display' in config[page.username]['page_security_level'](page.url) or interp_kind == None): include_interpreter(interp_kind, page, uid) log_id = util.extract_log_id(vlam) if log_id: t = 'interpreter' config[page.username]['logging_uids'][uid] = (log_id, t) else: log_id = False show = False # then we can go ahead and add html markup, extracting the Python # code to be executed in the process - we will not need this code; # this could change in a future version where we could add a button to # have the code automatically "injected" and executed by the # interpreter, thus saving some typing by the user. python_code = util.extract_code(elem) if util.is_interpreter_session(python_code): elem.attrib['title'] = "pycon" python_code = util.extract_code_from_interpreter(python_code) else: elem.attrib['title'] = "python" dummy, show_vlam = plugin['services'].style(page, elem, None, vlam) elem.attrib['title'] = vlam if log_id: config[page.username]['log'][log_id] = [tostring(elem)] util.wrap_in_div(elem, uid, vlam, "interpreter", show_vlam) if config[page.username][ 'popups'] and interp_kind is not None and not page.includes( "interpreter_helper"): page.add_include("interpreter_helper") # insert popup helper img = Element("img", src="/images/help.png", style="height:32px;", title="cluetip Hello %s! " % page.username + titles[interp_kind], rel=help_files[interp_kind]) elem.append(img) plugin['services'].insert_cluetip(page, img, uid) plugin['services'].insert_io_subwidget(page, elem, uid, interp_kind=interp_kind, sample_code=python_code, show=show) plugin['services'].insert_tooltip(page, elem, uid) return
def pdb_widget_callback(page, elem, uid): """Handles embedding suitable code into the page in order to display and run pdb""" # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, to make # thus making the source easier to read. if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("pdb_included"): page.add_include("pdb_included") #element tree always escape < to < and break my js code , so... page.insert_js_file("/pdb_js%s.js" % plugin['session_random_id']) if not page.includes("pdb_css_code"): page.add_include("pdb_css_code") page.add_css_code(pdb_css) # next, we style the code, also extracting it in a useful form ... vlam = elem.attrib["title"] python_code = util.extract_code(elem) if util.is_interpreter_session(python_code): elem.attrib['title'] = "pycon" python_code = util.extract_code_from_interpreter(python_code) else: elem.attrib['title'] = "python" code, show_vlam = plugin['services'].style(page, elem, None, vlam) elem.attrib['title'] = vlam util.wrap_in_div(elem, uid, vlam, "pdb", show_vlam) plugin['services'].insert_editor_subwidget(page, elem, uid, python_code) t = SubElement(elem, "h4", style="background-color:white;color:darkblue;") t.text = _("Local Namespace") local_ns_div = SubElement(elem, "div") local_ns_div.attrib["id"] = "local_ns_%s" % uid #some spacing: SubElement(elem, "br") btn = SubElement(elem, "button") btn.text = _("Start PDB") btn.attrib["onclick"] = "init_pdb('%s');" % (uid) btn.attrib["id"] = "btn_start_pdb_%s" % uid btn = SubElement(elem, "button") btn.text = _("Next Step") btn.attrib["id"] = "btn_next_step_%s" % uid btn.attrib["disabled"] = "disabled" btn = SubElement(elem, "button") btn.text = _("Step Into") btn.attrib["id"] = "btn_step_into_%s" % uid btn.attrib["disabled"] = "disabled" btn = SubElement(elem, "button") btn.text = _("Return") btn.attrib["id"] = "btn_return_%s" % uid btn.attrib["disabled"] = "disabled" btn = SubElement(elem, "button") btn.text = _("Next Multiple Steps") btn.attrib["id"] = "btn_next_many_steps_%s" % uid btn.attrib["disabled"] = "disabled" input1 = SubElement(elem, 'input', id='input_many_' + uid, size='4', value='1') t = SubElement(elem, "h4", style="background-color:white;color:darkblue;") t.text = _("Output") # finally, an output subwidget: plugin['services'].insert_io_subwidget(page, elem, uid) #register before_ouput hook plugin['services'].register_io_hook('before_output', pdb_filter, uid) #create pdb file cache for uid pdb_py_files[uid] = {}