def render(jinctx, obj): if isinstance(obj, dict): # Look for a rule named <type>_rule, then <role>_rule rule = None for prefix in (obj.get("type"), obj.get("role")): if not prefix: continue macroname = "%s_rule" % prefix if macroname in jinctx.exported_vars: rule = jinctx.vars[macroname] break if rule is None: if "default" in jinctx.exported_vars: rule = jinctx.vars["default"] else: return self.default_rule(jinctx, obj, render) return rule(obj) elif isinstance(obj, (list, tuple)) or inspect.isgenerator(obj): return functions.string(render(jinctx, o) for o in obj) else: return escape(functions.string(obj))
def default_rule(jinctx, obj, render): # Default action for blocks that don't have an associated rule if isinstance(obj, (list, tuple)): return functions.string(obj) elif isinstance(obj, dict): return "".join((render(jinctx, obj.get("text", ())), render(jinctx, obj.get("body", ())))) else: return escape(functions.string(obj))
def debug_wiki(path): from bookish.grammars.wiki import blocks from bookish.parser import parser, rules pages = flaskapp.get_wikipages(manager.app) src = wikipages.condition_string(pages.content(path)) ctx = wikipages.bootstrap_context() i = 0 blist = [] t = util.perf_counter() missed = False while rules.streamend.accept(src, i, ctx)[0] is parser.Miss: tt = util.perf_counter() out, newi = blocks(src, i, ctx) tt = util.perf_counter() - tt if not isinstance(out, dict): lines = parser.Lines(src) line, col = lines.line_and_col(i) print("Miss at line", line, "column", col, "(char %s)" % i) print(repr(src[i:i+10])) missed = True break i = newi blist.append((tt, out.get("type"), repr(functions.string(out.get("text"))[:40]))) t = util.perf_counter() - t print("%0.06f" % t) if not missed: blist.sort(reverse=True) for tt, typename, txt in blist: print("%0.06f" % tt, typename, txt)
def _template_for_page(self, templatename, jsondata): if not templatename: pagetype = string(jsondata.get("attrs", {}).get("type")) typetemplate = "/templates/%s.jinja2" % pagetype if pagetype and self.store.exists(typetemplate): templatename = typetemplate if not templatename: templatename = self.page_template return self.env.get_template(templatename)
def _get_method_names(self, block): methodnames = set() section = functions.subblock_by_id(block, "methods") if section: for methblock in functions.find_items(section, "methods_item"): text = functions.string(methblock.get("text")) name = text.split("(")[0] methodnames.add(name) return methodnames
def title_block(self, block): if self.pagetype == "hscript": self.emit_block_text(block, indent=-4) self._replaced_by() elif self.pagetype == "expression": name = functions.string(block.get("text")) # Pull out the usage section usage = functions.subblock_by_id(self.root, "usage") if usage and "body" in usage and usage["body"]: firstb = usage["body"][0] varnames = [functions.string(span) for span in functions.find_spans_of_type(firstb, "var")] self.emit(name + u" " + u" ".join(varnames)) else: self.emit(name) self._replaced_by() else: self.render_super(block) self._replaces()
def _make_doc(self, pages, path, root, block, text): attrs = block.get("attrs", {}) blocktype = block.get("type") body = block.get("body") is_root = blocktype == "root" # If a title was not passed in: if this is the root, look for a title # block, otherwise use the block text title = self._get_title(block) or paths.basename(path) container = False path = paths.basepath(path) if is_root: # Store a boolean if this page has subtopics subtopics = functions.subblock_by_id(block, "subtopics") container = subtopics and bool(subtopics.get("body")) else: blockid = functions.block_id(block) path = "%s#%s" % (path, blockid) # Look for a summary block summary = self._get_block_text(body, "summary") # Look for tags in the page attributes tags = attrs.get("tags", "").strip().replace(",", "") # Find outgoing links outgoing = [] for link in functions.find_links(block): val = link.get("value") if val: outgoing.append(pages.full_path(path, val)) outgoing = " ".join(outgoing) doctype = attrs.get("type") d = { "path": path, "status": attrs.get("status"), "category": "_", "content": functions.string(text), "title": title, "sortkey": attrs.get("sortkey") or title.lower(), "summary": summary, "grams": title, "type": doctype, "tags": tags, "icon": attrs.get("icon"), "links": outgoing, "container": container, "parent": self._get_path_attr(block, path, attrs, "parent"), "bestbet": attrs.get("bestbet"), } return d
def _flatten(self, block): if not self._should_index_block(block): return if "text" in block: yield functions.string(block["text"]) if "body" in block: for subblock in block["body"]: for text in self._flatten(subblock): yield text
def getParsedTooltip(url, content): if content.lstrip().startswith("<"): # TODO: Pull a tooltip out of raw HTML return None path = urlToPath(url) if not path: return pages = get_pages() json = pages.string_to_json(path, content, postprocess=False) body = json.get("body", ()) summary = functions.first_subblock_of_type(body, "summary") if summary: return functions.string(summary)
def find_parm(root, parmid, label): """ Tries to find a parameter in a help document, based on the parameter ID and its label. """ from bookish.util import dump_tree section = functions.subblock_by_id(root, "parameters") if section: parameters = functions.find_items(section, "parameters_item") for parmblock in parameters: if functions.block_id(parmblock) == parmid: return parmblock elif functions.string(parmblock.get("text")).strip() == label: return parmblock
def _flatten_with_docs(self, pages, path, root, block, docs): if not self._should_index_block(block): return if "text" in block: yield functions.string(block["text"]) if "body" in block: for subblock in block["body"]: if self._should_index_document(pages, path, root, subblock): self._block_to_doc(pages, path, root, subblock, docs, recurse=False) else: for text in self._flatten_with_docs(pages, path, root, subblock, docs): yield text
def format_block(block, lexername=None, lexer=None, pre=False): attrs = block.get("attrs", {}) source = functions.string(block.get("text", "")) look = attrs.get("display", "") lexername = lexername or block.get("lang") lexer = lexer or lexer_for(lexername) if "linenos" in attrs and attrs["linenos"] == "true": look += " linenos" if "hl_lines" in attrs: hl_lines = [int(n) for n in attrs["hl_lines"].strip("[]").split(",")] else: hl_lines = None return format_string(source, lexername, lexer, look, hl_lines, pre)
def apply(self, block, context, itemtype=None): # If this is a section... if block.get("role") == "section": # Give it a title if it doesnt have one if not block.get("text"): block["text"] = functions.string(block["id"]).capitalize() # Take its ID and make an item type from it itemtype = block["id"] + "_item" blocktype = block.get("type") if blocktype == "item" and itemtype: # If we're in a section, change this item's type to one based on # the section ID block["type"] = itemtype elif block.get("body"): # Recurse inside containers, passing down the item type for subblock in block.get("body", ()): self.apply(subblock, context, itemtype)
def _process_load_block(block, context): pages = context.pages attrs = block.setdefault("attrs", {}) egpath = attrs.get("path") egfile = attrs.get("examplefile") title = functions.string(block.get("text")) body = block.get("body") if egpath: # If the user gave a path to an example description file, load # it and use it to fill in any missing bits egsrc = pages.source_path(egpath) if pages.exists(egsrc): egdata = pages.json(egpath, context) egbody = egdata.get("body", []) # Fill in example file path if not egfile: attrs["examplefile"] = egdata.get("examplefile") # Fill in example text body if not body and attrs.get("include") == "yes": block["body"] = egbody # Fill in example title if not title: tb = functions.first_subblock_of_type(egbody, "title") block["text"] = tb.get("text", [])
def _superclasses(self, pages, methodnames, context, block, history=None): # Recursively loads the doc pointed to by the block's "superclass" # attribute and yields a (path, rootblock) pair for each superclass history = history or set() attrs = block.get("attrs", {}) superclass = attrs.get("superclass") if superclass: path = "/hom/" + superclass.replace(".", "/") spath = pages.source_path(path) if pages.exists(spath): if spath in history: raise Exception("Circular superclass structure") else: history.add(spath) doc = pages.json(spath, conditional=context.get("conditional"), postprocess=False) titleblock = functions.first_subblock_of_type(doc, "title") if titleblock: title = functions.string(titleblock.get("text")) else: title = superclass # Find the method items on the superclass section = functions.subblock_by_id(doc, "methods") methods = [] if section: for methblock in functions.find_items(doc, "methods_item"): text = methblock.get("text") name = functions.string(text).split("(")[0] attrs = methblock.get("attrs", {}) body = methblock.get("body", []) # If this name is in the set of seen methods, it's # overridden, so we should skip it if name in methodnames: continue methodnames.add(name) # Copy information about the method into a dict summary = functions.first_subblock_string(methblock) methdict = { "name": name, "text": text, "summary": summary, "more": len(body) > 1, } if "status" in attrs: methdict["status"] = attrs["status"] methods.append(methdict) yield { "path": path, "title": title, "methods": methods } for x in self._superclasses(pages, methodnames, context, doc, history): yield x
def _get_title(self, block): if block.get("type") == "root": return functions.string(block.get("title")).strip() else: return functions.string(block.get("text")).strip()
def _get_block_text(body, typename): for block in body: if block.get("type") == typename: return functions.string(block.get("text")) return ""
def hstring(text): return textify.dechar(functions.string(text)).encode("utf8")
def find_by_attr(top, name, value): for b in functions.find_all_breadth(top): if name == "id" and functions.string(b.get("id")) == value: yield b elif "attrs" in b and functions.string(b["attrs"].get(name)) == value: yield b
def test_string_function(): ls = ["01", "11"] assert functions.string(ls) == "0111"