def get_suggestions_for_string(highlight, string, xri): """ Returns highlight, string_with_suggestions """ suggestions = get_suggestions(xri) string_with_suggestions = apply_suggestions(string, suggestions) for where, replacement in suggestions: if where.character < where.character_end: orig = where.string[where.character:where.character_end] if replacement.strip(): tooltip = 'Aesthetic suggestion: replace “%s” with “%s”.' % ( orig, replacement) bulb = '\xf0\x9f\x92\xa1' tooltip += ' The “%sbeautify” button on the top right does it for you.' % bulb klass = "suggestion" else: tooltip = 'Fix indentation.' klass = 'indentation' elif where.character == where.character_end: if replacement.strip(): tooltip = 'Add “%s”.' % replacement klass = 'suggestion' else: tooltip = 'Fix indentation.' klass = 'indentation' highlight = html_mark(highlight, where, klass, tooltip=tooltip) return highlight, string_with_suggestions
def mark_errors(): s = """#comment mcdp { #@ syntax error }""" parse_expr = Syntax.ndpt_dp_rvalue x = parse_wrap(Syntax.ndpt_dp_rvalue, s)[0] context = Context() xr = parse_ndp_refine(x, context) suggestions = get_suggestions(xr) # make sure we can apply them _s2 = apply_suggestions(s, suggestions) def postprocess(block): x = parse_ndp_refine(block, context) return x html = ast_to_html(s, parse_expr=parse_expr, add_line_gutter=False, encapsulate_in_precode=False, postprocess=postprocess) text = project_html(html) s2 = """#comment mcdp { syntax error }""" assert_equal(text, s2) assert not '#@' in text
def check_mark_suggestions(): s = """#comment mcdp { provides a [Nat] }""" parse_expr = Syntax.ndpt_dp_rvalue x = parse_wrap(Syntax.ndpt_dp_rvalue, s)[0] context = Context() xr = parse_ndp_refine(x, context) suggestions = get_suggestions(xr) # make sure we can apply them _s2 = apply_suggestions(s, suggestions) def postprocess(block): x = parse_ndp_refine(block, context) return x html = ast_to_html(s, parse_expr=parse_expr, add_line_gutter=False, encapsulate_in_precode=False, postprocess=postprocess) for where, replacement in suggestions: # @UnusedVariable #print('suggestion: %r' % replacement) html = html_mark(html, where, "suggestion") assert 'suggestion' in html
def check_suggestions(filename, source): # @UnusedVariable # skip generated files (hack) if 'drone_unc2_' in filename: return # print filename source = open(filename).read() x = parse_wrap(Syntax.ndpt_dp_rvalue, source)[0] xr = parse_ndp_refine(x, Context()) suggestions = get_suggestions(xr) for w, r in suggestions: # @UnusedVariable #print('"%s" -> "%s"' % (w.string[w.character:w.character_end], r)) pass # print source.__repr__() print(source) s2 = apply_suggestions(source, suggestions) print(s2) # if suggestions: # print(s2) # do it a second time x = parse_wrap(Syntax.ndpt_dp_rvalue, s2)[0] xr = parse_ndp_refine(x, Context()) suggestions2 = get_suggestions(xr) s3 = apply_suggestions(s2, suggestions2) # the third time, there should not be any more suggestions x = parse_wrap(Syntax.ndpt_dp_rvalue, s3)[0] xr = parse_ndp_refine(x, Context()) suggestions3 = get_suggestions(xr) if suggestions3: msg = 'I expected that there are at most 2 rounds of suggestions.' raise_desc(ValueError, msg, s=source, s2=s2, s3=s3, suggestions=suggestions, suggestions2=suggestions2, suggestions3=suggestions3)
def try_corrections2(s): x = parse_wrap(Syntax.ndpt_dp_rvalue, s)[0] context = Context() xr = parse_ndp_refine(x, context) print indent(recursive_print(xr), 'xr|') suggestions = get_suggestions(xr) for orig_where, sub in suggestions: orig_1 = orig_where.string[orig_where.character:orig_where. character_end] print 'Change %r in %r' % (orig_1, sub) s2 = apply_suggestions(s, suggestions) #print s2 _x2 = parse_wrap(Syntax.ndpt_dp_rvalue, s2)[0] return s2
def get_suggestions_ndp(s): x = parse_wrap(Syntax.ndpt_dp_rvalue, s)[0] assert_equal(x.where.string, s) xr = parse_ndp_refine(x, Context()) suggestions = get_suggestions(xr) return suggestions
def go(selector, parse_expr, extension, use_pre=True, refine=None): for tag in soup.select(selector): source_code = '<unset>' # XXX try: if tag.string is None: # or not tag.string.strip(): if not tag.has_attr('id'): msg = "If <pre> is empty then it needs to have an id." raise_desc(ValueError, msg, tag=describe_tag(tag)) # load it tag_id = tag['id'].encode('utf-8') if '.' in tag_id: i = tag_id.index('.') libname, name = tag_id[:i], tag_id[i + 1:] use_library = library.load_library(libname) else: name = tag_id use_library = library basename = '%s.%s' % (name, extension) data = use_library._get_file_data(basename) source_code = data['data'] else: source_code = get_source_code(tag) # prettify. # remove spurious indentation source_code = source_code.strip() do_apply_suggestions = (not tag.has_attr('noprettify') and not tag.has_attr('np')) # then apply suggestions try: if do_apply_suggestions: x = parse_wrap(parse_expr, source_code)[0] xr = parse_ndp_refine(x, Context()) suggestions = get_suggestions(xr) source_code = apply_suggestions( source_code, suggestions) except DPSyntaxError as e: if raise_errors: raise else: res.note_error(str(e), HTMLIDLocation.for_element(tag)) continue # we don't want the browser to choose different tab size # source_code = source_code.replace('\t', ' ' * 4) # we are not using it _realpath = realpath context = Context() def postprocess(x): if refine is not None: return refine(x, context=context) else: return x # print('rendering source code %r' % source_code) html = ast_to_html(source_code, parse_expr=parse_expr, add_line_gutter=False, postprocess=postprocess) for w in context.warnings: if w.where is not None: from mcdp_web.editor_fancy.app_editor_fancy_generic import html_mark html = html_mark(html, w.where, "language_warning") frag2 = BeautifulSoup(html, 'lxml', from_encoding='utf-8') if use_pre: rendered = Tag(name='div', attrs={'class': 'rendered'}) pre = frag2.pre pre.extract() rendered.append(pre) if not rendered.has_attr('class'): rendered['class'] = "" if tag.has_attr('label'): text = tag['label'] tag_label = Tag(name='span') add_class(tag_label, 'label') add_class(tag_label, 'label_inside') tag_label.append(NavigableString(text)) pre.insert(0, tag_label) tag_label_outside = Tag(name='span') add_class(tag_label_outside, 'label') add_class(tag_label_outside, 'label_outside') tag_label_outside.append(NavigableString(text)) rendered.insert(0, tag_label_outside) max_len = max_len_of_pre_html(html) if tag.has_attr('label'): add_class(rendered, 'has_label') max_len = max(max_len, len(tag['label']) + 6) style = '' else: # using <code> rendered = frag2.pre.code rendered.extract() if not rendered.has_attr('class'): rendered['class'] = "" style = '' if tag.has_attr('style'): style = style + tag['style'] if style: rendered['style'] = style if tag.has_attr('class'): add_class(rendered, tag['class']) if tag.has_attr('id'): rendered['id'] = tag['id'] if use_pre: if generate_pdf: pdf = get_ast_as_pdf(source_code, parse_expr) if tag.has_attr('id'): basename = tag['id'] else: hashcode = hashlib.sha224( source_code).hexdigest()[-8:] basename = 'code-%s' % hashcode docname = os.path.splitext( os.path.basename(realpath))[0] download = docname + '.' + basename + '.source_code.pdf' a = create_a_to_data(download=download, data_format='pdf', data=pdf) a['class'] = 'pdf_data' a.append(NavigableString(download)) div = Tag(name='div') div.append(rendered) div.append(a) tag.replaceWith(div) else: tag.replaceWith(rendered) else: tag.replaceWith(rendered) except DPSyntaxError as e: if raise_errors: raise else: res.note_error(str(e), HTMLIDLocation.for_element(tag)) # note_error(tag, e) if tag.string is None: tag.string = "`%s" % tag['id'] continue except DPSemanticError as e: if raise_errors: raise else: res.note_error(str(e), HTMLIDLocation.for_element(tag)) # note_error(tag, e) if tag.string is None: tag.string = "`%s" % tag['id'] continue except DPInternalError as ex: msg = 'Error while interpreting the code:\n\n' msg += indent(source_code, ' | ') raise_wrapped(DPInternalError, ex, msg, exc=sys.exc_info())