97 lines
2.8 KiB
Python
97 lines
2.8 KiB
Python
|
#!/usr/bin/env python
|
||
|
|
||
|
from pathlib import Path
|
||
|
import re
|
||
|
|
||
|
# Tasks
|
||
|
# 1. Find all tutorials
|
||
|
# 2. Generate tree (@subpage)
|
||
|
# 3. Check prev/next nodes
|
||
|
|
||
|
class Tutorial(object):
|
||
|
def __init__(self, path):
|
||
|
self.path = path
|
||
|
self.title = None # doxygen title
|
||
|
self.children = [] # ordered titles
|
||
|
self.prev = None
|
||
|
self.next = None
|
||
|
with open(path, "rt") as f:
|
||
|
self.parse(f)
|
||
|
|
||
|
def parse(self, f):
|
||
|
rx_title = re.compile(r"\{#(\w+)\}")
|
||
|
rx_subpage = re.compile(r"@subpage\s+(\w+)")
|
||
|
rx_prev = re.compile(r"@prev_tutorial\{(\w+)\}")
|
||
|
rx_next = re.compile(r"@next_tutorial\{(\w+)\}")
|
||
|
for line in f:
|
||
|
if self.title is None:
|
||
|
m = rx_title.search(line)
|
||
|
if m:
|
||
|
self.title = m.group(1)
|
||
|
continue
|
||
|
if self.prev is None:
|
||
|
m = rx_prev.search(line)
|
||
|
if m:
|
||
|
self.prev = m.group(1)
|
||
|
continue
|
||
|
if self.next is None:
|
||
|
m = rx_next.search(line)
|
||
|
if m:
|
||
|
self.next = m.group(1)
|
||
|
continue
|
||
|
m = rx_subpage.search(line)
|
||
|
if m:
|
||
|
self.children.append(m.group(1))
|
||
|
continue
|
||
|
|
||
|
def verify_prev_next(self, storage):
|
||
|
res = True
|
||
|
|
||
|
if self.title is None:
|
||
|
print("[W] No title")
|
||
|
res = False
|
||
|
|
||
|
prev = None
|
||
|
for one in self.children:
|
||
|
c = storage[one]
|
||
|
if c.prev is not None and c.prev != prev:
|
||
|
print("[W] Wrong prev_tutorial: expected {} / actual {}".format(c.prev, prev))
|
||
|
res = False
|
||
|
prev = c.title
|
||
|
|
||
|
next = None
|
||
|
for one in reversed(self.children):
|
||
|
c = storage[one]
|
||
|
if c.next is not None and c.next != next:
|
||
|
print("[W] Wrong next_tutorial: expected {} / actual {}".format(c.next, next))
|
||
|
res = False
|
||
|
next = c.title
|
||
|
|
||
|
if len(self.children) == 0 and self.prev is None and self.next is None:
|
||
|
print("[W] No prev and next tutorials")
|
||
|
res = False
|
||
|
|
||
|
return res
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
|
||
|
p = Path('tutorials')
|
||
|
print("Looking for tutorials in: '{}'".format(p))
|
||
|
|
||
|
all_tutorials = dict()
|
||
|
for f in p.glob('**/*'):
|
||
|
if f.suffix.lower() in ('.markdown', '.md'):
|
||
|
t = Tutorial(f)
|
||
|
all_tutorials[t.title] = t
|
||
|
|
||
|
res = 0
|
||
|
print("Found: {}".format(len(all_tutorials)))
|
||
|
print("------")
|
||
|
for title, t in all_tutorials.items():
|
||
|
if not t.verify_prev_next(all_tutorials):
|
||
|
print("[E] Verification failed: {}".format(t.path))
|
||
|
print("------")
|
||
|
res = 1
|
||
|
|
||
|
exit(res)
|