def expandMacro(self, opts): attributes = parseTagAttributes("expand-macro", opts, [ "name", "vars" ]) if not "name" in attributes: fatal("expand-macro: No macro name given: " + line) template = self.get([ "macro" ], attributes["name"]) if "vars" in attributes: keys = parseOption("expand-macro", attributes["vars"]) else: keys = {} return template.expand(keys)
def chapterTemplates(self, lines, properties, meta): # Figure out what template name to use. if "template-chapter" in properties: chapterTemplateName = properties["template-chapter"] else: chapterTemplateName = "default" if "template-chapter-first" in properties: chapterTemplateNameFirst = properties["template-chapter-first"] else: chapterTemplateNameFirst = "default-first" dprint(1, "Chapter Template: Using first: " + chapterTemplateNameFirst + \ ", subsequent: " + chapterTemplateName) # Now we can set the globals, since we have now extracted all the metadata self.setGlobals(meta) # Figure out which templates we are going to use. tFirst = self.get([ "chapter" ], chapterTemplateNameFirst) t = self.get([ "chapter" ], chapterTemplateName) regexMacro = re.compile("<expand-macro\s+(.*?)/?>") i = 0 first = True while i < len(lines): line = lines[i] if line.startswith("<chap-head"): keys = {} opts, keys["chap-head"] = parseLineEntry("chap-head", line) j = i+1 while j < len(lines) and re.match(lines[j], "^\s*$"): j += 1 if j == len(lines): fatal("End of file after <chap-head>") if opts != "": attributes = parseTagAttributes("chap-head", opts, [ "vars" ]) dprint(1, "<chap-head> attributes: " + str(attributes)) if "vars" in attributes: vars = parseOption("chap-head", attributes["vars"]) dprint(1, "<chap-head> vars: " + str(vars)) keys.update(vars) line = lines[j] if line.startswith("<sub-head"): opts, keys["sub-head"] = parseLineEntry("sub-head", line) else: # Do not eat this line! j -= 1 # If the first we've seen, it starts the book if first: templ = tFirst first = False else: templ = t dprint(1, "expand keys: " + str(keys)) replacement = templ.expand(keys) dprint(2, "replace " + str(lines[i:j+1]) + " with " + str(replacement)) lines[i:j+1] = replacement i += len(replacement) continue if line.startswith("<sub-head>"): fatal("Found <sub-head> not after a <chap-head>: " + line) # What about multiple macro expansions on a line? Or recursion? # Make it simpler for now by just punting: if you expand, then we move on # to the next line. m = regexMacro.search(line) if m: opts = m.group(1) attributes = parseTagAttributes("expand-macro", opts, [ "name", "vars" ]) if not "name" in attributes: fatal("expand-macro: No macro name given: " + line) template = self.get([ "macro" ], attributes["name"]) if "vars" in attributes: keys = parseOption("expand-macro", attributes["vars"]) else: keys = {} replacement = template.expand(keys) prefix = line[:m.start(0)] suffix = line[m.end(0):] if len(replacement) == 0: # If the template returns nothing, then you end up with a single line of # the prefix and suffix around the <expand-macro> replacement = [ prefix + suffix ] else: # Otherwise the prefix goes on the first line; and the suffix at the end of # the last; which might be the same single line. replacement[0] = prefix + replacement[0] replacement[-1] = replacement[-1] + suffix lines[i:i+1] = replacement i += len(replacement) continue i += 1