### 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("", "") else: new_content += "" if need_rewrite: with open(file_path, mode="w", encoding="gbk", errors="ignore") as f: f.write(new_content) print(f"{file_path} — auto-corrected and saved") # Run against the entire project (invoked directly when the script is executed) walk_through_files(checkout) # Expected output example: # /path/DND5e_chm/某书/某页.htm — missing coding declaration # /path/DND5e_chm/某书/某页.htm — auto-corrected and saved ``` -------------------------------- ### Convert HTML to TXT with BeautifulSoup Source: https://context7.com/dnd5echm/dnd5e_chm/llms.txt Converts HTML files to UTF-8 encoded TXT files, preserving directory structure. It attempts to auto-detect encoding (UTF-8, GBK, latin-1) and uses BeautifulSoup for parsing, handling specific tags like
,

, and for formatting. ```python from bs4 import BeautifulSoup import os, re def transform_html_2_txt(base_path: str, output_path: str = None): """ Convert all HTML files under base_path to UTF-8 .txt files. Output mirrors the source directory tree under output_path. """ if not os.path.isdir(base_path): raise ValueError(f"Directory not found: {base_path}") if output_path is None: output_path = base_path for root, _, files in os.walk(base_path): for file in files: if not file.lower().endswith((".html", ".htm")): continue html_path = os.path.join(root, file) rel_path = os.path.relpath(root, base_path) txt_path = os.path.join(output_path, rel_path, os.path.splitext(file)[0] + ".txt") os.makedirs(os.path.dirname(txt_path), exist_ok=True) # Auto-detect encoding: UTF-8 → GBK → latin-1 content = None for enc in ["utf-8", "gbk", "latin-1"]: try: with open(html_path, "r", encoding=enc) as f: content = f.read() break except UnicodeDecodeError: continue soup = BeautifulSoup(content, "html.parser") parts = [] for el in soup.descendants: if el.name is None: parts.append(el.replace("\n", "")) elif el.name == "br": parts.append("\n") elif el.name in ["p","div","h1","h2","h3","h4","h5","h6","li","table","tr"]: parts.append("\n\n") elif el.name == "td": parts.append(" ") text = re.sub(r"\n+", "\n", "".join(parts)).strip() text = text.replace("\u2018", "'" ).replace("\u2019", "'") with open(txt_path, "w", encoding="utf-8") as f: f.write(text) print(f"Converted: {html_path} -> {txt_path}") # --- CLI usage --- # python 不全书转txt.py [base_path] [output_path] # Default base_path = project root # Default output_path = Generator/Generated/txt/ # Programmatic example: convert only the 玩家手册2024 book transform_html_2_txt( base_path="/path/to/DND5e_chm/玩家手册2024", output_path="/tmp/phb2024_txt" ) # Expected output: # Converted: .../玩家手册2024/创建角色/专长.htm -> /tmp/phb2024_txt/创建角色/专长.txt # ... ``` -------------------------------- ### Fix CSS Path Depth in HTML Files Source: https://context7.com/dnd5echm/dnd5e_chm/llms.txt Updates relative paths in `` tags to ensure correct stylesheet loading. It calculates the necessary prefix (`./`, `../`, `../../`) based on the file's directory depth. ```python # Generator/2024style定向.py import os from 文件遍历 import get_base_path, walk_through_files base_path = get_base_path() def fix_style_link(file_path: str, file_name: str): with open(file_path, mode="r", encoding="gbk") as f: data = f.read() if '' not in data: return # no stylesheet link to fix link_start = data.find('') rel_path = os.path.relpath(file_path, base_path) depth = rel_path.count("\\") # nesting level prefix = "./" # depth 1: file sits directly in a top-level folder if depth == 2: prefix = "../" # depth 2: one subfolder deep elif depth == 3: prefix = "../../" # depth 3: two subfolders deep data = data[:link_start] + prefix + data[css_marker:] with open(file_path, mode="w", encoding="gbk") as f: f.write(data) print(f"Fixed [{depth}] {rel_path}") # Fix all files inside 玩家手册2024 walk_through_files(fix_style_link, "玩家手册2024") ```