def processAnchors(anchors, doc): for anchor in anchors: if "type" not in anchor or len(anchor['type']) != 1: die("Each anchor needs exactly one type. Got:\n{0}", config.printjson(anchor)) continue if "text" not in anchor or len(anchor['text']) != 1: die("Each anchor needs exactly one text. Got:\n{0}", config.printjson(anchor)) continue if "url" not in anchor and "urlPrefix" not in anchor: die("Each anchor needs a url and/or at least one urlPrefix. Got:\n{0}", config.printjson(anchor)) continue if "urlPrefix" in anchor: urlPrefix = ''.join(anchor['urlPrefix']) else: urlPrefix = "" if "url" in anchor: urlSuffix = anchor['url'][0] else: urlSuffix = config.simplifyText(anchor['text'][0], convertDashes=anchor['type'][0] == "dfn") url = urlPrefix + ("" if "#" in urlPrefix or "#" in urlSuffix else "#") + urlSuffix if anchor['type'][0] in config.lowercaseTypes: anchor['text'][0] = anchor['text'][0].lower() doc.refs.refs[anchor['text'][0]].append({ "linkingText": anchor['text'][0], "type": anchor['type'][0], "url": url, "shortname": doc.md.shortname, "level": doc.md.level, "for": anchor.get('for', []), "export": True, "status": "local", "spec": anchor.get('spec', [''])[0] }) return []
def processLinkDefaults(lds, doc): for ld in lds: if len(ld.get('type', [])) != 1: die("Every link default needs exactly one type. Got:\n{0}", config.printjson(ld)) continue else: type = ld['type'][0] if len(ld.get('spec', [])) != 1: die("Every link default needs exactly one spec. Got:\n{0}", config.printjson(ld)) continue else: spec = ld['spec'][0] if len(ld.get('text', [])) != 1: die("Every link default needs exactly one text. Got:\n{0}", config.printjson(ld)) continue else: text = ld['text'][0] if 'for' in ld: for _for in ld['for']: doc.md.linkDefaults[text].append( (spec, type, ld.get('status', None), _for)) else: doc.md.linkDefaults[text].append( (spec, type, ld.get('status', None), None)) return []
def processAnchors(anchors, doc, lineNum=None): for anchor in anchors: if "type" not in anchor or len(anchor['type']) != 1: die("Each anchor needs exactly one type. Got:\n{0}", config.printjson(anchor), lineNum=lineNum) continue if "text" not in anchor or len(anchor['text']) != 1: die("Each anchor needs exactly one text. Got:\n{0}", config.printjson(anchor), lineNum=lineNum) continue if "url" not in anchor and "urlPrefix" not in anchor: die("Each anchor needs a url and/or at least one urlPrefix. Got:\n{0}", config.printjson(anchor), lineNum=lineNum) continue if "urlPrefix" in anchor: urlPrefix = ''.join(anchor['urlPrefix']) else: urlPrefix = "" if "url" in anchor: urlSuffix = anchor['url'][0] else: urlSuffix = config.simplifyText(anchor['text'][0]) url = urlPrefix + ("" if "#" in urlPrefix or "#" in urlSuffix else "#") + urlSuffix if anchor['type'][0] in config.lowercaseTypes: anchor['text'][0] = anchor['text'][0].lower() doc.refs.refs[anchor['text'][0]].append({ "linkingText": anchor['text'][0], "type": anchor['type'][0], "url": url, "shortname": doc.md.shortname, "level": doc.md.level, "for": anchor.get('for', []), "export": True, "status": "local", "spec": anchor.get('spec', [''])[0] }) methodishStart = re.match(r"([^(]+\()[^)]", anchor['text'][0]) if methodishStart: arglessName = methodishStart.group(1) + ")" doc.refs.addMethodVariants(anchor['text'][0], anchor.get('for', []), doc.md.shortname) return []
def processLinkDefaults(lds, doc): for ld in lds: if len(ld.get('type', [])) != 1: die("Every link default needs exactly one type. Got:\n{0}", config.printjson(ld)) continue if len(ld.get('spec', [])) != 1: die("Every link default needs exactly one spec. Got:\n{0}", config.printjson(ld)) continue if len(ld.get('text', [])) != 1: die("Every link default needs exactly one text. Got:\n{0}", config.printjson(ld)) continue doc.md.linkDefaults[ld['text'][0]].append((ld['spec'][0], ld['type'][0], ld.get('status', None), ld.get('for', None))) return []
def transformLinkDefaults(lines, doc, **kwargs): lds = parseInfoTree(lines, doc.md.indent) for ld in lds: if len(ld.get('type', [])) != 1: die("Every link default needs exactly one type. Got:\n{0}", config.printjson(ld)) continue if len(ld.get('spec', [])) != 1: die("Every link default needs exactly one spec. Got:\n{0}", config.printjson(ld)) continue if len(ld.get('text', [])) != 1: die("Every link default needs exactly one text. Got:\n{0}", config.printjson(ld)) continue doc.md.linkDefaults[ld['text'][0]].append((ld['spec'][0], ld['type'][0], ld.get('status', None), ld.get('for', None))) return []
def processLinkDefaults(lds, doc): for ld in lds: if len(ld.get("type", [])) != 1: die("Every link default needs exactly one type. Got:\n{0}", config.printjson(ld)) continue if len(ld.get("spec", [])) != 1: die("Every link default needs exactly one spec. Got:\n{0}", config.printjson(ld)) continue if len(ld.get("text", [])) != 1: die("Every link default needs exactly one text. Got:\n{0}", config.printjson(ld)) continue doc.md.linkDefaults[ld["text"][0]].append( (ld["spec"][0], ld["type"][0], ld.get("status", None), ld.get("for", None)) ) return []
def processIgnoredSpecs(specs, doc): for spec in specs: if len(spec.get('spec', [])) == 0: die( "Every ignored spec line needs at least one 'spec' value. Got:\n{0}", config.printjson(spec)) continue specNames = spec.get('spec') if len(spec.get('replacedBy', [])) > 1: die( "Every ignored spec line needs at most one 'replacedBy' value. Got:\n{0}", config.printjson(spec)) continue replacedBy = spec.get( 'replacedBy')[0] if 'replacedBy' in spec else None for specName in specNames: if replacedBy: doc.refs.replacedSpecs.add((specName, replacedBy)) else: doc.refs.ignoredSpecs.add(specName) return []
def processAnchors(anchors, doc): for anchor in anchors: if "type" not in anchor or len(anchor["type"]) != 1: die("Each anchor needs exactly one type. Got:\n{0}", config.printjson(anchor)) continue if "text" not in anchor or len(anchor["text"]) != 1: die("Each anchor needs exactly one text. Got:\n{0}", config.printjson(anchor)) continue if "url" not in anchor and "urlPrefix" not in anchor: die("Each anchor needs a url and/or at least one urlPrefix. Got:\n{0}", config.printjson(anchor)) continue if "urlPrefix" in anchor: urlPrefix = "".join(anchor["urlPrefix"]) else: urlPrefix = "" if "url" in anchor: urlSuffix = anchor["url"][0] else: urlSuffix = config.simplifyText(anchor["text"][0]) url = urlPrefix + ("" if "#" in urlPrefix or "#" in urlSuffix else "#") + urlSuffix if anchor["type"][0] in config.lowercaseTypes: anchor["text"][0] = anchor["text"][0].lower() doc.refs.refs[anchor["text"][0]].append( { "linkingText": anchor["text"][0], "type": anchor["type"][0], "url": url, "shortname": doc.md.shortname, "level": doc.md.level, "for": anchor.get("for", []), "export": True, "status": "local", "spec": anchor.get("spec", [""])[0], } ) methodishStart = re.match(r"([^(]+\()[^)]", anchor["text"][0]) if methodishStart: arglessName = methodishStart.group(1) + ")" doc.refs.methods[arglessName].append(anchor["text"][0]) return []
def processLinkDefaults(lds, doc, lineNum=None): for ld in lds: if len(ld.get('type', [])) != 1: die("Every link default needs exactly one type. Got:\n{0}", config.printjson(ld), lineNum=lineNum) continue else: type = ld['type'][0] if len(ld.get('spec', [])) != 1: die("Every link default needs exactly one spec. Got:\n{0}", config.printjson(ld), lineNum=lineNum) continue else: spec = ld['spec'][0] if len(ld.get('text', [])) != 1: die("Every link default needs exactly one text. Got:\n{0}", config.printjson(ld), lineNum=lineNum) continue else: text = ld['text'][0] if 'for' in ld: for _for in ld['for']: doc.md.linkDefaults[text].append((spec, type, ld.get('status', None), _for)) else: doc.md.linkDefaults[text].append((spec, type, ld.get('status', None), None)) return []
def transformAnchors(lines, doc, **kwargs): anchors = parseInfoTree(lines, doc.md.indent) for anchor in anchors: if "type" not in anchor or len(anchor['type']) != 1: die("Each anchor needs exactly one type. Got:\n{0}", config.printjson(anchor)) continue if "text" not in anchor or len(anchor['text']) != 1: die("Each anchor needs exactly one text. Got:\n{0}", config.printjson(anchor)) continue if "url" not in anchor and "urlPrefix" not in anchor: die("Each anchor needs a url and/or at least one urlPrefix. Got:\n{0}", config.printjson(anchor)) continue for key in anchor: if key not in ("type", "text", "url", "urlPrefix", "for"): die("Unknown key '{0}' in anchor:\n{1}", key, config.printjson(anchor)) continue if "urlPrefix" in anchor: urlPrefix = ''.join(anchor['urlPrefix']) else: urlPrefix = "" if "url" in anchor: urlSuffix = anchor['url'][0] else: urlSuffix = config.simplifyText(anchor['text'][0], convertDashes=anchor['type'][0] == "dfn") url = urlPrefix + ("" if "#" in urlPrefix or "#" in urlSuffix else "#") + urlSuffix if anchor['type'][0] in config.lowercaseTypes: anchor['text'][0] = anchor['text'][0].lower() doc.refs.refs[anchor['text'][0]].append({ "linkingText": anchor['text'][0], "type": anchor['type'][0], "url": url, "for": anchor.get('for', []), "export": True, "status": "local" }) return []
def processInfo(infos, doc, lineNum=None): knownInfoTypes = { "anchors": processAnchors, "link-defaults": processLinkDefaults, "ignored-specs": processIgnoredSpecs } infoCollections = defaultdict(list) for info in infos: if len(info.get('info', [])) != 1: die("Every info-block line needs exactly one 'info' type. Got:\n{0}", config.printjson(info), lineNum=lineNum) continue infoType = info.get('info')[0].lower() if infoType not in knownInfoTypes: die("Unknown info-block type '{0}'", infoType, lineNum=lineNum) continue infoCollections[infoType].append(info) for infoType, infos in infoCollections.items(): knownInfoTypes[infoType](infos, doc, lineNum=0) return []
def processInfo(infos, doc): knownInfoTypes = { "anchors": processAnchors, "link-defaults": processLinkDefaults, "ignored-specs": processIgnoredSpecs } infoCollections = defaultdict(list) for info in infos: if len(info.get('info', [])) != 1: die("Every info-block line needs exactly one 'info' type. Got:\n{0}", config.printjson(info)) continue infoType = info.get('info')[0].lower() if infoType not in knownInfoTypes: die("Unknown info-block type '{0}'", infoType) continue infoCollections[infoType].append(info) for infoType, infos in infoCollections.items(): knownInfoTypes[infoType](infos, doc) return []
def processIgnoredSpecs(specs, doc, lineNum=None): for spec in specs: if len(spec.get('spec', [])) == 0: die("Every ignored spec line needs at least one 'spec' value. Got:\n{0}", config.printjson(spec), lineNum=lineNum) continue specNames = spec.get('spec') if len(spec.get('replacedBy', [])) > 1: die("Every ignored spec line needs at most one 'replacedBy' value. Got:\n{0}", config.printjson(spec), lineNum=lineNum) continue replacedBy = spec.get('replacedBy')[0] if 'replacedBy' in spec else None for specName in specNames: if replacedBy: doc.refs.replacedSpecs.add((specName, replacedBy)) else: doc.refs.ignoredSpecs.add(specName) return []
def processAnchors(anchors, doc, lineNum=None): for anchor in anchors: if "type" not in anchor or len(anchor['type']) != 1: die("Each anchor needs exactly one type. Got:\n{0}", config.printjson(anchor), lineNum=lineNum) continue if "text" not in anchor or len(anchor['text']) != 1: die("Each anchor needs exactly one text. Got:\n{0}", config.printjson(anchor), lineNum=lineNum) continue if "url" not in anchor and "urlPrefix" not in anchor: die("Each anchor needs a url and/or at least one urlPrefix. Got:\n{0}", config.printjson(anchor), lineNum=lineNum) continue if "urlPrefix" in anchor: urlPrefix = ''.join(anchor['urlPrefix']) else: urlPrefix = "" if "url" in anchor: urlSuffix = anchor['url'][0] else: urlSuffix = config.simplifyText(anchor['text'][0]) url = urlPrefix + ("" if "#" in urlPrefix or "#" in urlSuffix else "#") + urlSuffix status = "local" shortname = None level = None if "shortname" in anchor and "level" in anchor: shortname = anchor['shortname'][0] level = config.HierarchicalNumber(anchor['level'][0]) spec = anchor["spec"][0] if "spec" in anchor else None if shortname and not spec: if level: spec = "{0}-{1}".format(shortname, level) else: spec = shortname elif spec and not shortname: match = re.match("(.*)-(\d+)$", spec) if match: shortname = match.group(1) level = config.HierarchicalNumber(match.group(2)) else: shortname = spec level = config.HierarchicalNumber("") if "status" in anchor: status = anchor["status"][0] if status in config.linkStatuses: pass else: die("Anchor statuses must be {1}. Got '{0}'.", status, config.englishFromList(config.linkStatuses), lineNum=lineNum) continue else: status = "anchor-block" if anchor['type'][0] in config.lowercaseTypes: anchor['text'][0] = anchor['text'][0].lower() doc.refs.refs[anchor['text'][0]].append({ "linkingText": anchor['text'][0], "type": anchor['type'][0].lower(), "url": url, "shortname": shortname.lower() if shortname is not None else doc.md.shortname, "level": level if level is not None else doc.md.level, "for": anchor.get('for', []), "export": True, "status": status, "spec": spec.lower() if spec is not None else '' }) methodishStart = re.match(r"([^(]+\()[^)]", anchor['text'][0]) if methodishStart: doc.refs.addMethodVariants(anchor['text'][0], anchor.get('for', []), doc.md.shortname) return []
def processAnchors(anchors, doc, lineNum=None): for anchor in anchors: if "type" not in anchor or len(anchor['type']) != 1: die("Each anchor needs exactly one type. Got:\n{0}", config.printjson(anchor), lineNum=lineNum) continue if "text" not in anchor or len(anchor['text']) != 1: die("Each anchor needs exactly one text. Got:\n{0}", config.printjson(anchor), lineNum=lineNum) continue if "url" not in anchor and "urlPrefix" not in anchor: die("Each anchor needs a url and/or at least one urlPrefix. Got:\n{0}", config.printjson(anchor), lineNum=lineNum) continue if "urlPrefix" in anchor: urlPrefix = ''.join(anchor['urlPrefix']) else: urlPrefix = "" if "url" in anchor: urlSuffix = anchor['url'][0] else: urlSuffix = config.simplifyText(anchor['text'][0]) url = urlPrefix + ("" if "#" in urlPrefix or "#" in urlSuffix else "#") + urlSuffix status = "local" shortname = None level = None if "shortname" in anchor and "level" in anchor: shortname = anchor['shortname'][0] level = config.HierarchicalNumber(anchor['level'][0]) spec = anchor["spec"][0] if "spec" in anchor else None if shortname and not spec: if level: spec = "{0}-{1}".format(shortname, level) else: spec = shortname elif spec and not shortname: match = re.match("(.*)-(\d+)$", spec) if match: shortname = match.group(1) level = config.HierarchicalNumber(match.group(2)) else: shortname = spec level = config.HierarchicalNumber("") if "status" in anchor: status = anchor["status"][0] if status in config.linkStatuses: pass else: die("Anchor statuses must be {1}. Got '{0}'.", status, config.englishFromList(config.linkStatuses), lineNum=lineNum) continue else: status = "anchor-block" if anchor['type'][0] in config.lowercaseTypes: anchor['text'][0] = anchor['text'][0].lower() doc.refs.anchorBlockRefs.refs[anchor['text'][0]].append({ "linkingText": anchor['text'][0], "type": anchor['type'][0].lower(), "url": url, "shortname": shortname.lower() if shortname is not None else doc.md.shortname, "level": level if level is not None else doc.md.level, "for": anchor.get('for', []), "export": True, "status": status, "spec": spec.lower() if spec is not None else '' }) methodishStart = re.match(r"([^(]+\()[^)]", anchor['text'][0]) if methodishStart: doc.refs.anchorBlockRefs.addMethodVariants(anchor['text'][0], anchor.get('for', []), doc.md.shortname) return []