def _process_doc(self, pages, path, root, block, doc): # Add Houdini-specific fields to each document path = paths.basepath(path) attrs = block.get("attrs", {}) doctype = attrs.get("type", "").strip() context = attrs.get("context", "").strip().replace(",", "") or None if doctype == "node": if context in ("pop", "part") or context.endswith("_state"): return internal = attrs.get("internal") if internal: doc["grams"] += " %s" % internal if doc.get("category") == "_": if path.startswith("/shelf/"): doc["category"] = "tool" elif path.startswith("/ref/util/"): doc["category"] = "utility" elif path.startswith("/gallery/shop/"): doc["category"] = "gallery/shop" elif doctype == "node": doc["category"] = "%s/%s" % (doctype, context) doc["grams"] += " %s" % context elif doctype in ("hscript", "expression", "example", "homclass", "hommodule", "vex"): doc["category"] = doctype replaces = attrs.get("replaces") rsection = functions.subblock_by_id(block, "replaces") if rsection: rlist = " ".join(link.get("fullpath", "") for link in functions.find_links(rsection)) if replaces: replaces = replaces + " " + rlist else: replaces = rlist doc.update({ "context": context, "bestbet": attrs.get("bestbet"), "helpid": attrs.get("helpid"), "superclass": attrs.get("superclass"), "version": attrs.get("version"), "replaces": replaces or None, "examplefor": root.get("examplefor"), "examplefile": root.get("examplefile"), "group": attrs.get("group"), }) # Add example file info if root is block and "examplefile" in root: otlpath = root["examplefile"] # Usages file should be in the same location with .usages ext usagespath = paths.basepath(otlpath) + ".usages" if pages.exists(usagespath): usagescontent = pages.content(usagespath) usages = ws_exp.split(usagescontent) doc["uses"] = " ".join(usages)
def _apply(context, item, basepath, depth, maxdepth): pages = context.pages # Find the first link in the item and use its path text = item.get("text") link = functions.first_span_of_type(text, "link") if not link: return ref = link.get("value") if not ref or ":" in ref: return fullpath = pages.full_path(basepath, ref) if not pages.exists(fullpath): return # Load the referenced page json = pages.json(fullpath, context) # Find the subtopics section subtopics = functions.subblock_by_id(json, "subtopics") if not subtopics: return # Copy the subtopics onto this topic's body if "body" in subtopics: body = copy.deepcopy(subtopics["body"]) # Collapse certain block types body = functions.collapse(body, ("col_group", "col")) item["body"] = body if depth < maxdepth: # Recurse on the loaded subtopics topics = functions.find_items(subtopics, "subtopics_item") for subitem in topics: Toc._apply(context, subitem, fullpath, depth + 1, maxdepth)
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 _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 apply(self, block, context): basepath = paths.basepath(context.get("path")) # Find the subtopics section subtopics = functions.subblock_by_id(block, "subtopics") if not subtopics: return attrs = subtopics.get("attrs", {}) maxdepth = int(attrs.get("maxdepth", "0")) if not maxdepth: return topics = functions.find_items(subtopics, "subtopics_item") for item in topics: self._apply(context, item, basepath, 1, maxdepth)
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 _parent_info(json, path): # Find the subtopics section subtopics = functions.subblock_by_id(json, "subtopics") if subtopics: stbody = subtopics.get("body") if stbody: # Remove body = functions.collapse(stbody, ("col_group", "col")) subtopics["body"] = body return { "path": path, "basepath": paths.basepath(path), "title": json.get("title", ()), "summary": json.get("summary", ()), "attrs": json.get("attrs", {}), "subtopics": subtopics, }
def apply(self, block, context): btype = block.get("type") if btype == "root": attrs = block.get("attrs", {}) if attrs.get("type") == "node": parmsblock = functions.subblock_by_id(block, "parameters") if parmsblock: self.apply(parmsblock, context) elif block.get("type") == "dt": block["type"] = "parameters_item" block["role"] = "item" elif block.get("type") == "dt_group": block["type"] = "parameter_group" for subblock in block.get("body", ()): self.apply(subblock, context) elif block.get("container"): for subblock in block.get("body", ()): self.apply(subblock, context)
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 _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