File size: 3,095 Bytes
1bd64c1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | #!/usr/bin/env python3
"""
Cisco IOS IP Routing: OSPF Command Reference parser.
Same bold-backtick format as the Arista EOS User Guide but Cisco-flavored.
All 113 commands → vendor=Cisco, os=ios, cat=OSPF (no recat needed — they're all OSPF).
"""
import re, json, pathlib
from collections import Counter
SRC = pathlib.Path(__file__).parent / "sources" / "cisco-ios-ospf-reference.md"
OUT = pathlib.Path(__file__).parent / "cisco_ospf.json"
TITLE_RE = re.compile(r"^\*\*`([^`]+)`\*\*\s*$")
def parse():
text = SRC.read_text(encoding="utf-8", errors="ignore")
lines = text.split("\n")
out = []
section_hdr = "OSPF"
pending_title = None
i, n = 0, len(lines)
while i < n:
line = lines[i]
m = re.match(r"^#{2,3}\s+(.+?)\s*$", line)
if m:
section_hdr = m.group(1).strip()
i += 1; continue
m = TITLE_RE.match(line)
if m:
pending_title = m.group(1).strip()
i += 1; continue
if line.strip().startswith("```"):
block = []
i += 1
while i < n and not lines[i].strip().startswith("```"):
block.append(lines[i]); i += 1
i += 1
# Description (markdown blockquote)
desc = ""
j = i
while j < n and j < i + 6:
ln = lines[j].strip()
if not ln: j += 1; continue
qm = re.match(r"^>\s*(.+?)\s*$", lines[j])
if qm:
parts = [qm.group(1)]
k = j + 1
while k < n:
qq = re.match(r"^>\s*(.+?)\s*$", lines[k])
if qq: parts.append(qq.group(1)); k += 1
else: break
desc = " ".join(parts).strip()
break
cleaned = [l for l in block if l.strip()]
if not cleaned:
pending_title = None; continue
cmd = "\n".join(cleaned).rstrip()
first = cleaned[0].strip()
# Skip obvious output samples
if re.match(r"^(Active|Up|Down|Login:|Username:|--More--|Area\s+\d|i\s*\[)", first):
pending_title = None; continue
title = pending_title or first[:80]
out.append({
"os":"ios","role":"router","vendor":"Cisco","cat":"OSPF",
"title": title[:80],
"cmd": cmd,
"desc": (desc or section_hdr)[:280],
})
pending_title = None
continue
i += 1
return out
def main():
items = parse()
# dedupe within this source
seen = set(); deduped = []
for it in items:
key = re.sub(r"\s+", " ", it["cmd"]).lower()
if key in seen: continue
seen.add(key); deduped.append(it)
OUT.write_text(json.dumps(deduped, indent=1, ensure_ascii=False))
print(f"wrote {len(deduped)} Cisco OSPF entries → {OUT}")
print("titles sample:", [c["title"][:50] for c in deduped[:5]])
if __name__ == "__main__":
main()
|