### Build Full Quick-Reference Table Source: https://context7.com/dnd5echm/dnd5e_chm/llms.txt Processes monster data from HTML files to build a comprehensive quick-reference table. It detects file encoding, parses HTML content to extract monster details, and writes the compiled list to an HTML file. ```python big_monster_list: dict[str, Monster] = {} def process_file(file_path: str, file_name: str): with open(file_path, "rb") as f: enc = chardet.detect(f.read())["encoding"] or "gbk" with open(file_path, "r", encoding=enc, errors="ignore") as f: data = f.read() body = data[data.find("
")+6 : data.find("")] soup = BeautifulSoup(body, "html.parser") for h5 in soup.find_all("h5"): fragment = "".join(str(s) for s in h5.self_and_next_siblings if not (s.name == "h5" and s is not h5)) monster = Monster(fragment, file_path, "MM25") big_monster_list[monster.monster_id] = monster for folder in monster_file_list: walk_through_files(process_file, folder) # Render output rows = [m.output_id_and_link() for m in sorted(big_monster_list.values(), key=lambda m: m.monster_id)] with open("../速查/5E万兽大全.html", "w", encoding="gbk", errors="ignore") as f: f.write(template_big.replace("怪物列表内容", "\n".join(rows))) ``` -------------------------------- ### Generate WinCHM Project File (.wcp) from Directory Structure Source: https://context7.com/dnd5echm/dnd5e_chm/llms.txt This script uses Tkinter to let the user select a directory and then generates a WinCHM-compatible `.wcp` project file. The project file includes a topic tree that mirrors the selected folder's hierarchy, encoded in UTF-16-LE. ```Python # Generator/文件夹做WCP.py — run via run.bat import os import codecs import tkinter as tk from tkinter import filedialog PREFIX = """[GENERAL] Ver=1 Title=5E 不全书子书 ... [TOPICS] TitleList=""" # Workflow (runs on __main__) root = tk.Tk() root.withdraw() # 1. User picks a folder (e.g. D:/DND5e_chm/城主指南2024) file_path = filedialog.askdirectory(title="选择所用的文件夹", initialdir="../") if file_path: wcp_name = os.path.basename(file_path) # e.g. "城主指南2024" relative_file_path = os.path.relpath(file_path, "../") object_list = [] for folder, dirs, files in os.walk(file_path): folder_name = os.path.basename(folder) relative_path = os.path.relpath(folder, "../") depth = relative_path.count("/") + relative_path.count("\\") object_list.append([folder_name, "", depth]) # directory node for name in files: file_rel = os.path.relpath(os.path.join(folder, name), "../") object_list.append([name.split(".")[0], file_rel, depth + 1]) # file node # Build WCP topic entries entries = [] for i, (title, url, level) in enumerate(object_list): entries.append( f"TitleList.Title.{i}={title}\n" f"TitleList.Level.{i}={level}\n" f"TitleList.Url.{i}={url}\n" f"TitleList.Status.{i}=0\n" f"TitleList.Keywords.{i}=\n" f"TitleList.ContextNumber.{i}={i+1000}\n" f"TitleList.ApplyTemp.{i}=0\n" f"TitleList.Expanded.{i}=0\n" f"TitleList.Kind.{i}=0" ) # Write UTF-16-LE encoded .wcp file output_path = f"../{wcp_name}_生成.wcp" with open(output_path, "wb") as f: f.write(codecs.BOM_UTF16_LE) f.write((PREFIX + str(len(object_list))).encode("utf-16-le")) for entry in entries: f.write(("\n" + entry).encode("utf-16-le")) print(f"Generated: {output_path}") # Expected output: Generated: ../城主指南2024_生成.wcp ``` -------------------------------- ### Batch Replace Link Paths in Web Help Files Source: https://context7.com/dnd5echm/dnd5e_chm/llms.txt Applies a list of (old, new) string substitutions to a UTF-8 encoded file in-place. Reports the number of replacements made for a given file. ```python import os def process_file(file_path: str, replace_rules: list[tuple[str, str]]): """Apply a list of (old, new) string substitutions to a UTF-8 file in-place.""" with open(file_path, "r", encoding="utf-8") as f: content = f.read() count = sum(content.count(old) for old, _ in replace_rules) for old, new in replace_rules: content = content.replace(old, new) if count: with open(file_path, "w", encoding="utf-8") as f: f.write(content) print(f"[OK] {os.path.basename(file_path)}: {count} replacements") # Fix relative hrefs in the Web Help export of the monster index process_file( r"output\\Web Help\\topics\\速查\\5E万兽大全.html", [(' list: """ Walk `path`, detect each file's encoding, and re-save as GB18030. Skips files already in GBK. Returns list of (dir, name, old_enc, new_enc). """ converted = [] for root, _, files in os.walk(path): for file in files: if not any(file.endswith(t) for t in file_types): continue fpath = os.path.join(root, file) with open(fpath, "rb") as f: raw = f.read() for enc in ["gbk", "utf-8-sig", "utf-8", "big5", "utf-16"]: try: decoded = raw.decode(enc) if enc != "gbk": with codecs.open(fpath, "w", encoding="GB18030") as f: f.write(decoded) converted.append((root, file, enc, "GB18030")) else: converted.append((root, file, "gbk", "gbk")) break except UnicodeDecodeError: continue return converted results = convert_to_gbk(r"C:\\DND5e_chm\\速查", file_types=[".htm", ".html"]) # Output: C:\\DND5e_chm\\速查-5E万兽大全.html-utf-8-GB18030 ``` -------------------------------- ### Check and Correct CHM File Encoding and Content Source: https://context7.com/dnd5echm/dnd5e_chm/llms.txt This script iterates through files, ensuring correct GBK encoding and the presence of a tag with sufficient content. It automatically corrects missing declarations and missing body tags, rewriting files to GBK encoding if initially read as UTF-8. ```Python from 文件遍历 import walk_through_files NEEDTOBE = 20 # minimum body character count before flagging a page as empty def checkout(file_path: str, file_name: str): if "空白页模板" in file_path or "$$unsavedpage" in file_name: return # skip template/draft files need_rewrite = False try: with open(file_path, mode="r", encoding="gbk") as f: content = f.read() except UnicodeDecodeError: with open(file_path, mode="r", encoding="utf-8") as f: content = f.read() need_rewrite = True # UTF-8 file must be converted to GBK new_content = content # 1. Ensure GBK coding declaration is present if "coding: gbk" not in new_content: new_content = "" + new_content need_rewrite = True print(f"{file_path} — missing coding declaration") # 2. Check for tags and body content length left = content.find("") if content.find("") != -1 else content.find("") if left != -1 and right != -1: body_content = content[content.find(">", left) + 1 : right] if len(body_content) < NEEDTOBE: print(f"{file_path} — body has fewer than {NEEDTOBE} chars: {body_content!r}") else: print(f"{file_path} — missing tag, attempting auto-repair") need_rewrite = True if "" in new_content: new_content = new_content.replace("", "") if "" in new_content: new_content = new_content.replace("