From cec38b8c25ecd41516f8e06826219f7c95941853 Mon Sep 17 00:00:00 2001
From: Pavel Tsayukov
Date: Wed, 30 Oct 2024 22:47:32 +0300
Subject: [PATCH] Add script generating wiki (#57)
---
__tests__/docs/generate.py | 91 ++++++++++++++++++++++++++++++++++++++
1 file changed, 91 insertions(+)
create mode 100644 __tests__/docs/generate.py
diff --git a/__tests__/docs/generate.py b/__tests__/docs/generate.py
new file mode 100644
index 0000000..b49bc93
--- /dev/null
+++ b/__tests__/docs/generate.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python3
+
+import os
+import re
+import sys
+
+from dataclasses import dataclass, field
+from typing import Any, ClassVar
+
+
+@dataclass(eq=False, slots=True)
+class WikiPageGenerator:
+ """Class for generating an .md file as a wiki page"""
+ directory: str
+ is_active: bool = field(default=False, init=False)
+ n_equal_signs: int = field(default=0, init=False)
+
+ title_forbidden_pattern: ClassVar[re.Pattern] = re.compile(r"[\\/:*?\"<>|]|\s")
+ open_pattern: ClassVar[re.Pattern] = re.compile(r"^\s*#\[(=*)\[#github\/wiki\s*$")
+ close_pattern: ClassVar[re.Pattern] = re.compile(r"^\s*#\](=*)\]#github\/wiki\s*$")
+
+ def __open(self, n_equal_signs: int):
+ if self.is_active:
+ raise RuntimeError((f"Current WikiPageGenerator is already active: "
+ "unexpected the opening wiki comment"))
+ self.n_equal_signs = n_equal_signs
+ self.is_active = True
+
+ def __close(self, n_equal_signs: int):
+ if not self.is_active:
+ raise RuntimeError((f"Current WikiPageGenerator is not active: "
+ "unexpected the closing wiki comment"))
+ if self.n_equal_signs != n_equal_signs:
+ raise RuntimeError((f"Expected {self.n_equal_signs} equal signs, "
+ "but got: {n_equal_signs}"))
+ self.n_equal_signs = 0
+ self.is_active = False
+
+ def __find_first__opening_wiki_comment(self, line_generator: Any) -> bool:
+ for line in line_generator:
+ m: re.Match | None = re.match(WikiPageGenerator.open_pattern, line)
+ if m is not None:
+ equal_signs: str = m[1]
+ self.__open(len(equal_signs))
+ return True
+ return False
+
+ def __find_wiki_title(self, line_generator: Any) -> str:
+ for line in line_generator:
+ index: int = line.find("#")
+ if index != -1 and len(line) > index + 1 and line[index + 1] != "#":
+ title: str = line[index+1:].strip()
+ return re.sub(WikiPageGenerator.title_forbidden_pattern, "-", title)
+ raise RuntimeError("The wiki title is not found. Expected form: '# '")
+
+ def __write_to_wiki(self, file: Any, line: str):
+ m: re.Match | None = re.match(WikiPageGenerator.close_pattern, line)
+ if m is not None:
+ equal_signs: str = m[1]
+ self.__close(len(equal_signs))
+ return
+
+ m = re.match(WikiPageGenerator.open_pattern, line)
+ if m is not None:
+ equal_signs: str = m[1]
+ self.__open(len(equal_signs))
+ return
+
+ if not self.is_active:
+ return
+
+ file.write(f"{line}")
+
+ def generate_from(self, line_generator: Any):
+ """Generate an .md file in `self.directory` with documentation from `line_generator`"""
+ if not self.__find_first__opening_wiki_comment(line_generator):
+ return
+
+ wiki_title: str = self.__find_wiki_title(line_generator)
+ file_path: str = os.path.join(self.directory, f"{wiki_title}.md")
+ with open(file_path, "w", encoding="utf-8") as doc:
+ doc.write(f"# {wiki_title}\n")
+ for line in line_generator:
+ self.__write_to_wiki(doc, line)
+
+
+if __name__ == "__main__":
+ wiki_dir: str = sys.argv[1]
+ module_path: str = sys.argv[2]
+ with open(module_path, "r", encoding="utf-8") as module:
+ WikiPageGenerator(wiki_dir).generate_from(module)