from collections import defaultdict import random import yaml import chevron import sys class GrawlixCodex(): def __init__(self, width=55, wordcount=50000, chaplength=4000, parlength=400): self.width = width self.smallest = 1 self.longest = 6 self.wordcount = wordcount self.chapleast = int(chaplength * 0.8) self.chapmost = int(chaplength * 1.2) self.parleast = int(parlength * 0.5) self.parmost = int(parlength * 1.5) def config(self, cffile): with open(cffile) as cf: try: self.cf = yaml.load(cf, Loader=yaml.Loader) except yaml.YAMLError as exc: print("%s parse error: %s" % ( self.args.config, exc )) if hasattr(exc, 'problem_mark'): mark = exc.problem_mark print("Error position: (%s:%s)" % (mark.line + 1, mark.column + 1)) def load_emojos(self): self.emojos = [] self.groups = defaultdict(set) with open(self.cf["emojos"], "r") as efh: for line in efh: parts = line.split() glyph = parts[0][1:-1] self.emojos.append(glyph) for tag in parts[1:]: self.groups[tag].add(glyph) self.tags = [ t for t in self.groups.keys() if not t == "blank" ] self.blank = list(self.groups["blank"])[0] def word(self): l = random.randint(self.smallest, self.longest) for g in range(l): yield random.choice(list(self.groups["glyph"])) def text(self): p = 0 parlength = random.randint(self.parleast, self.parmost) for w in range(self.wordcount): if w % 1000 == 0: print(f"{w} words", file=sys.stderr) for g in self.word(): yield g if random.randint(1, 10) > 8: yield random.choice(list(self.groups["colour"])) p += 1 if p == parlength: yield(":par:") p = 0 parlength = random.randint(self.parleast, self.parmost) else: yield(self.blank) def line(self, gs, cls): glyphs = [ f'' for g in gs ] return ''.join(glyphs) + "
\n" def chap_title(self): title = [] for w in range(1, random.randint(1, 5)): for g in self.word(): title.append(g) title.append(self.blank) title = title[:-1] title.append(random.choice(list(self.groups["colour"]))) return title def chapters(self): chap_length = random.randint(self.chapleast, self.chapmost) n = 0 row = [] html = "" for g in self.text(): if g != ":par:" and not ( g == "grawlix_null" and len(row) == 0): row.append(g) if len(row) == self.width or g == ":par:": html += self.line(row, "gl") row = [] if g == ":par:": html += "
" n += 1 if n > chap_length: chap_length = random.randint(self.chapleast, self.chapmost) n = 0 yield { "title": self.line(self.chap_title(), "ct"), "text": html } gc = GrawlixCodex(wordcount=50000, chaplength=10000) gc.config("./config.yml") gc.load_emojos() n = 1; chapters = list(gc.chapters()) index = [] for i in range(0, len(chapters)): c = chapters[i] c["nav"] = "" ci = i + 1 fn = f"chapter_{ci}.html" index.append({ "link": fn, "title": c["title"] }) n = i + 2 if i < len(chapters) - 1: c["nav"] = f'' c["nav"] += chapters[i + 1]["title"] + '' with open("chapter.mustache", "r") as tf: with open(f"output/{fn}", "w") as cf: print(chevron.render(tf, c), file=cf) print(f"Chapter {ci}", file=sys.stderr) with open("index.mustache", "r") as tf: with open(f"output/index.html", "w") as cf: print(chevron.render(tf, {"index": index}), file=cf) print("Index", file=sys.stderr)