if __name__ == "__main__": import sys sys.path.append("../kutil") sys.path.append("../target") import re import klammer_base import kutil import html_util from html_util import E import latex_util as L import pprint import phases def escape_newlines(s): return re.sub("\n", " ___NL___ ", s) # def literal_newline(s): # def replace(match): # before, after = match.groups() # return f"{before}\\n{after}" # backslash_pat = re.compile(r'(".*?)\n(.*?")', re.S) # return backslash_pat.sub(replace, s) def get_blocks(s): comment_pat = re.compile(r"(\s*)//(\d+)\s+(.*)", re.S) blocks = [] lines = s.strip("\n").split("\n") i = 0 uncommented = "" while i < len(lines): match = comment_pat.match(lines[i]) if match: if uncommented: blocks.append([uncommented.rstrip(), None]) uncommented = "" count = int(match.group(2)) comment = match.group(3) code = "" j = 0 i += 1 while j < count: line = re.sub("\n", "\\n", lines[i]) code += line + "\n" j += 1 i += 1 blocks.append([code.strip("\n"), comment]) else: uncommented += lines[i] + "\n" i += 1 if uncommented: blocks.append([uncommented.rstrip(), None]) return blocks def latex_spaces(s): def replace(match): s = match.group(0) if False and len(s) == 1: return "~" else: result = "~" * len(s) result = f"\\hphantom{{{result}}}" return result space_pat = re.compile(" +", re.S) return space_pat.sub(replace, s) def latex_unquote(s): quoted = "asciicircum quotesingle asciigrave asciitilde asciitilde backslash".split() quoted = [f"{{}}\text{e}{{}}" for e in quoted] result = s for q in quoted: result = re.sub(q, "X", result) result = re.sub(" ", "Y", result) return result def longest_line(s): result = "" for line in latex_unquote(s).split("\n"): if len(line) > len(result): result = line return result def literal_newline(s): def replace(match): before, after = match.groups() return f"{before}\\n{after}" backslash_pat = re.compile(r'(".*?)\n(.*?")', re.S) return backslash_pat.sub(replace, s) class Code(klammer_base.Klammer_base): id = 0 def __init__(self, K): super().__init__(K) self.text = phases.expand_whitespace_markers(self.text) def html(self): if self.K_target == "html": self.text = literal_newline(self.text) # Escape Klammertext special characters so they survive # re-insertion into the katom stream after @eval self.text = self.text.replace("^", "^^") self.text = self.text.replace("#", "^#") self.text = self.text.replace("@", "^@") self.text = self.text.replace("|", "^|") self.blocks = get_blocks(self.text) result = '' for text, comment in self.blocks: border = "code_border" if comment else "code_no_border" body = E("div").body(text).cls(f"code_text {border}").str(None) if comment: body += "\n" + E("div").body(comment).cls("code_comment").str() result += E("div").body(body).cls("code_block").str() if self.number or self.caption: #result = html_util.add_caption( # result, "Listing", self.number, self.caption, "i", "left", "top") caption = kutil.caption_marker("Listing", self.caption) result = f'
\n{self.src}\n\n'
# result = self.src
# result = undash(result)
# result = f'\n{result}\n\n'
# return result
# def tex(self):
# src = self.src
# src = re.sub(r"\\{", "{", src)
# src = re.sub(r"\\}", "}", src)
# result = f"\\begin{{lstlisting}}\n{src}\n\\end{{lstlisting}}\n"
# return result
# def txt(self):
# return "x~ " + self.src
# class Pathname(klammer_base.Klammer_base):
# def __init__(self, K):
# super().__init__(K)
# def html(self):
# return f'{self.s}'
# def tex(self):
# result = self.s
# def replace(match):
# return '\\{}'.format(match.group(1))
# result = re.sub(r'\\', 'XXXBACKSLASHXXX', result)
# result = re.compile('\s*__UNSPACE__\s*', re.S).sub('', result)
# result = re.compile(r'([&${}%#_])').sub(replace, result)
# result = re.sub('\^', r'\\^{}', result)
# result = re.sub('~', r'\\~{}', result)
# result = re.sub(r'XXXBACKSLASHXXX', r'{\\textbackslash}', result)
# result = re.sub('\n', r'~\\\\\n', result.strip())
# result = re.sub(' ', '$~$', result)
# result = re.sub("'", r"{\\textquotesingle}", result)
# result = re.sub('"', r'{\\textquotedbl}', result)
# result = re.sub('--', '{-}{-}', result)
# result = r'{{\normalfont\texttt{{{}}}}}'.format(result.strip())
# result = re.sub(r'\{\\textbackslash\}\\#', '\\#', result)
# if self.small:
# result = '{{\\footnotesize{}}}'.format(result)
# return result
# def txt(self):
# return f"'{self.s}'"