import pprint import re import textwrap import kutil import klammer_base import phases import itertools import math from html_util import E class List(klammer_base.Klammer_base): def __init__(self, K, list_type): super().__init__(K) self.list_type = list_type self.items = self.list_items word_count = max([len(e.strip().split()) for e in self.items]) self.compressed = False #and word_count < int(self.List_compressed_word_max) def html(self): body = "" word_count = 0 for e in self.items: body += f"
  • \n{kutil.format_for_paragraphs(e.strip())}\n
  • \n" cls = "compressed" if self.compressed else "" result = E(self.list_type).cls(cls).body(body.strip()).str().strip() + "\n" return result def tex(self): body = "\n\n".join([f"\\item {e}" for e in self.items]) command = {'ol' : 'enumerate', 'ul' : 'itemize'}[self.list_type] init = "" if self.__dict__.get("initial") and self.initial != 1: init = "\\addtocounter{enumi}{" + str(self.initial - 1) + "}" #topsep = '[noitemsep,topsep=0pt]' topsep = "[noitemsep,topsep=0pt," if self.compressed else "[topsep=0pt,itemsep=2pt," topsep += "leftmargin=16pt]" listsep = '\\setlist{nolistsep}' if self.cmp else '' result = f'{listsep}\n\\begin{{{command}}}{topsep}{init}\n{body}\n\\end{{{command}}}\n' return result def txt(self): n = 1 result = "" for item in self.items: prefix = f"{n:3}. " if self.list_type == "ol" else " • " # U+2022 print("prefix", prefix) formatted_item = "\n".join( textwrap.wrap(item.strip(), width=80, subsequent_indent=" "*(len(prefix)))) result += f"{prefix}{formatted_item}\n" if not self.compressed: result += "\n" n += 1 return result class Define(klammer_base.Klammer_base): def __init__(self, K): super().__init__(K) self.items = self.descriptions #self.show() #pprint.pprint(self.items) def html(self): def fontify(s): return {"r" : s, "i" : f"{s}", "b" : f"{s}", "t" : f'{s}', "c" : f'{s}', "s" : f'{s}'}[self.style] result = "\n\n".join([f"
    {fontify(term)}
    \n
    {definition}
    " for term,definition in self.items]) result = f"
    \n{result}\n
    " return result def tex(self): def fontify(s): font = {'r' : r'\normalfont', 'i' : r'\normalfont\itshape', 'b' : r'\normalfont\bfseries', 't' : r'\normalfont\ttfamily', 'c' : r'\normalfont\ttfamily', 's' : r'\normalfont\sffamily'}[self.style] return f"{font} {s}" strut = r"\rule[-4pt]{0pt}{4pt}" result = "\n\n".join([f"\\item[{{{fontify(term)}{strut}}}] {definition}" for term,definition in self.items]) options = "style=nextline" # See list/list.sty result = f"\\begin{{description}}[{options}]\n{result}\n\\end{{description}}" return result def txt(self): # Plain text: each term on its own line at the block indent, its # definition beneath it indented once more, items separated by a # blank line. Every line begins with the nbsp marker, which is what # tells the justification pass the block is already laid out # (phases.txt_justify_blocks); a definition's own paragraphs are # wrapped to the remaining measure, and a paragraph that is already # laid out (it begins with the marker -- a @table inside the # definition) is only indented further. The term takes :style as # italic or bold, the styles a terminal can show. nbsp = phases.txt_nbsp_marker() indent = int(self.Target_txt_indent) term_indent, def_indent = nbsp * indent, nbsp * (2 * indent) measure = int(self.Target_txt_width) - 2 * indent style = {"i": "italic", "b": "bold"}.get(self.style) items = [] for term, definition in self.items: term = term.strip() if style and term: term = phases.txt_style_marker(style) + term + phases.txt_style_marker(style, False) paragraphs = [] for par in re.split(r"\n\s*\n", definition.strip()): if phases.txt_is_laid_out(par): paragraphs.append("\n".join(def_indent + line for line in par.split("\n"))) else: paragraphs.append("\n".join(def_indent + line for line in phases.txt_wrap(par, measure))) items.append(term_indent + term + "\n" + "\n\n".join(paragraphs)) return phases.txt_lay_out("\n\n".join(items)) class Lines(klammer_base.Klammer_base): def __init__(self, K): super().__init__(K) def html(self): #return "
    ".join(self.s.strip().split("\n")) #return f'
    {self.s}
    ' #return f'
    {self.s}
    ' result = self.s result = re.sub("\n", "
    \n", result) result = re.sub(" ", "&^#160;", result) return result def tex(self): return r"\\\newline\n".join(self.s.strip().split("\n")) def txt(self): return self.s.strip() class Columns(klammer_base.Klammer_base): def __init__(self, K): super().__init__(K) def make_column_lists(self): lst = [f"@{self.style} {e} {self.style}@" for e in self.items.split()] cols = math.ceil(len(lst) / self.n) result = [] for i in range(self.n): result.append(lst[i * cols : (i+1) * cols]) return list(itertools.zip_longest(*result, fillvalue="")) def columns(self): rows = self.make_column_lists() result = (f"@table :header false :number false :leading 1.0 " f":hpos {self.hpos} :offset {self.offset} |\n") for row in rows: result += " | ".join(row) + " ||\n" result += "table@\n" return result def html(self): return self.columns() def tex(self): return self.columns() def txt(self): return self.columns()