import pprint import re import textwrap import kutil import klammer_base 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 = kutil.rest_args(self.list_items) if self.items[-1].strip() == "": self.items = self.items[:-1] 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(int(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 == 'true' 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 print(result) return result class Define(klammer_base.Klammer_base): def __init__(self, K): super().__init__(K) self.items = kutil.rest_args(self.descriptions, 2) #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.font] 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.font] return f"{font} {s}" result = "\n\n".join([f"\\item[{fontify(term)}]\\hfill\n\\newline {definition}" for term,definition in self.items]) result = f"\\begin{{description}}[labelindent=12pt,nosep,itemsep=6pt]\n{result}\n\\end{{description}}" return result def txt(self): return "TXT DEFINITIONS" 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() """ def lines(K): return {'html' : html_lines, 'tex' : tex_lines, 'pdf' : tex_lines}[K._target](K) def tex_lines(K): return " \\\\\n".join(K.s.strip().split("\n")) def html_lines(K): return "
    ".join(K.s.strip().split("\n")) """ """ def definition_item(K): if K._format == 'html': return '
    {}
    \n
    {}
    '.format( format_for_paragraphs(K.term), format_for_paragraphs(K.desc)) else: leading = '' if K.inlist else '\\vspace*{-16pt}' return '\\item[{}]\\leavevmode{}\n\n{}'.format( K.term, leading, K.desc) """ """ def list(K, list_type): items = kutil.rest_args(K.list_items) return {'html' : html_list, 'tex' : tex_list, 'pdf' : tex_list}[K._target](K, list_type, items) def html_list(K, list_type, items): body = "\n" + "".join([E("li").body(e).str()+"\n" for e in items]) result = E(list_type).body(body).str().rstrip() return result def tex_list(K, list_type, items): body = "\n\n".join([f"\\item {e}" for e in items]) command = {'ol' : 'enumerate', 'ul' : 'itemize'}[list_type] topsep = '[topsep=0pt]' listsep = '\\setlist{nolistsep}' if K.cmp != 'false' else '' result = f'{listsep}\n\\begin{{{command}}}{topsep}\n{body}\n\\end{{{command}}}\n' return result def describe(K): items = "\n\n".join(kutil.rest_args(K.descriptions)) return {'html' : html_describe, 'tex' : tex_describe, 'pdf' : tex_describe}[K._target](K, items) def html_describe(K, items): return E("dl").body(items).str() def tex_describe(K, items): return f'\\begin{{description}}\n{items}\n\\end{{description}}' def entry(K): return {'html' : html_entry, 'tex' : tex_entry, 'pdf' : tex_entry}[K._target](K) def html_entry(K): #return f'
    {K.item}
    \n
    {K.description}
    ' return E("dt").body(K.item).str(0) + E("dd").body(K.description).str(0) def tex_entry(K): return f'\\item[{K.item}]\n{K.description}\n' def lines(K): return {'html' : html_lines, 'tex' : tex_lines, 'pdf' : tex_lines}[K._target](K) def tex_lines(K): return " \\\\\n".join(K.s.strip().split("\n")) def html_lines(K): return "
    ".join(K.s.strip().split("\n")) """ r""" # List items paragraph_separator_re = re.compile('\n *\n', re.S) def format_for_paragraphs(s): result = s if len(paragraph_separator_re.findall(result)) > 0: result = '\n\n{}\n\n'.format(result) return result def li(K): if K._format == 'html': result = K.s.strip() result = format_for_paragraphs(result) result = '
  • {}
  • '.format(result) else: #result = '\\item{{\\Kinlisttrue {}}} '.format(K.s.strip()) #result = '\\item\\begin\\Kinlisttrue {}\\end '.format(K.s.strip()) #result = '\\item\\parbox{{\\linewidth}}{{\\Kinlisttrue {}}} '.format(K.s.strip()) #result = '\\item\\Kinlisttrue {} '.format(K.s.strip()) result = '\\item {} '.format(K.s.strip()) if K.keep: result = '\\parbox{{\\linewidth}}{{{}}}'.format(result) return result def mli(K): result = '@0item {} | @0ulc\n'.format(K.args[0]) result += "\n".join(['@0li {} li@'.format(e) for e in K.args[1:]]) + '\n' result += ' ulc@ item@\n' return result # Ordered and unordered lists: def list_html(K, list_type): result = '' if K.list_items[0][0:4] != '
  • ': result = "\n".join(['
  • {}
  • '.format(e) for e in K.list_items]) else: result = K.list_items[0] tag = 'ol' if list_type == 'ul': tag = 'ul style="list-style-type:{};"'.format(K.bullet) cls = 'compressed' if K.cmp else '' if list_type == 'ul' and K.bullet == 'none': cls += ' nobullet' cls = ' class="{}"'.format(cls.strip()) result = '<{}{}>\n{}\n\n'.format(tag, cls, result, list_type) return result def list_latex(K, list_type): result = '' first_word = K.list_items[0][:5] if first_word not in {'\\item', '\\parb'}: result = " " + "\n".join(['@0li {} li@'.format(e.strip()) for e in K.list_items]) else: result = K.list_items[0] #options = 'nosep,itemsep=1pt,topsep=0pt,partopsep=8pt,parsep=4pt' options = 'nosep,itemsep={}pt'.format(2 if K.cmp else 6) if K.cmp: itemsep=',nosep' else: itemsep='' ''' if list_type == 'ul' and K.bullet == 'none' and K.indent: left_margin = ',leftmargin=18pt' else: left_margin = '' ''' left_margin = '' if K.in_define: if list_type == 'ul': left_margin = ',leftmargin=4pt' else: left_margin = ',leftmargin=16pt' if K.parsep: parsep = K.parsep else: parsep = 2 if K.cmp else 6 #options = '[nosep,parsep={}pt{},{}]'.format(parsep, left_margin,itemsep) options = '[parsep={}{}{}]'.format(parsep, left_margin, itemsep) ''' if K.cmp: options = '[nosep]' else: options = '' ''' #options = '[itemsep={}]'.format(K.itemsep) if K.itemsep else '' #options = '[topsep=0pt,parsep={}pt]'.format(2 if K.cmp else 6) #options = '\\setlength{{\\topsep}{0pt}}\n\\setlength{{\parsep}}{{{}}}\n'.format( bullet = '' if list_type == 'ul' and K.bullet == 'none': bullet = '\\renewcommand\\labelitemi{\\hspace*{-8pt}}' itemsep = '\n\\setlength{{\\itemsep}}{{{}}}\n'.format(K.itemsep) if K.itemsep else '' #result = '''\\listvmargin% result = '''\\begin{{{0}}}{1}{2} {3} {4} \\end{{{0}}} '''.format('itemize' if list_type == 'ul' else 'enumerate', options, itemsep, bullet, result.strip()) result = re.compile('\n\n', re.S).sub('\n', result) result = re.compile(r' +\\begin', re.S).sub(r'\\begin', result) if K.uncover: N = 1 def replace(match): nonlocal N result = '{}<{}-> '.format(match.group(1), N) N += 1 return result result = re.compile(r'(\\item(\[|\s))').sub(replace, result) return result #\\listvmargin def ul(K): if K._format == 'html': return list_html(K, 'ul') elif K._format == 'latex': return list_latex(K, 'ul') else: util.format_not_defined(K._format, 'ul') def ol(K): if K._format == 'html': return list_html(K, 'ol') elif K._format == 'latex': return list_latex(K, 'ol') else: util.format_not_defined(K._format, 'ol') # Definitions def definition_item(K): if K._format == 'html': return '
    {}
    \n
    {}
    '.format( format_for_paragraphs(K.term), format_for_paragraphs(K.desc)) else: leading = '' if K.inlist else '\\vspace*{-16pt}' return '\\item[{}]\\leavevmode{}\n\n{}'.format( K.term, leading, K.desc) def dfont(K): if K._format == 'latex': result = {'r' : '\\normalfont', 'i' : '\\normalfont\\itshape', 'b' : '\\normalfont\\bfseries', 't' : '\\normalfont\\ttfamily', 's' : '\\normalfont\\sffamily\\large' }[K.font] elif K._format == 'html': s = K.term result = {'r' : s, 'i' : '{}'.format(s), 'b' : '{}'.format(s), 't' : '{}'.format(s), 's' : '{}'.format(s) }[K.font] else: error.Klammertext_error( 'There is not defined format named "{}".'.format(K._format)) return result def escape_code_term(s): def replace(match): left, term, right = match.groups() term = re.sub('\[', r'$\\lbrack$\\,', term) term = re.sub('\]', r'\\,$\\rbrack$', term) #term = re.sub('\[', '\\[', term) #term = re.sub('\]', '\\]', term) term = re.sub('--', '-{}-', term) result = '{}{}{}'.format(left, term, right) return result pat = re.compile(r'(\\item\[)(.*?)(\]\\)', re.S) return pat.sub(replace, s) def define(K): if K._format == 'latex': #itemsep=1pt,topsep=2pt,partopsep=8pt,parsep=4pt,% options = 'nosep,parsep=4pt,leftmargin=32pt' fontname = {'r' : '\\normalfont', 'i' : '\\normalfont\\itshape', 'b' : '\\normalfont\\bfseries', 't' : '\\normalfont\\ttfamily', 's' : '\\normalfont\\sffamily', 'si' : '\\normalfont\\sffamily\\itshape', 'sb' : '\\normalfont\\sffamily\\bfseries', 'c' : '\\normalfont', }[K.font] term = K.s if K.font == 'c': term = escape_code_term(term) #term = re.compile('item\[(.*?)\]', re.S).sub(r'item[\\verb+\1+]', term) #term = re.compile(' return ''' \\listvmargin \\begin{{description}}[{}, labelindent=16pt,% style=nextline,font={}] %\\raggedright {} \\end{{description}} \\listvmargin\n'''.format(options,fontname, term) elif K._format == 'html': term_class = {'r' : 'normal', 'i' : 'italic', 'b' : 'bold', 't' : 'monospace', 's' : 'sansserifbody', 'si' : 'sansserifitalic', 'sb' : 'sansserifbold', 'c' : 'normal', }[K.font] term = K.s if K.font == 'c': #term = re.sub('–', '‐'*2, term) term = re.sub('–', '- __UNSPACE__ -', term) body = re.sub('
    ', '
    '.format(term_class), term) return '''
    {}
    '''.format(body) """ def make_column_lists(lst, count): cols = math.ceil(len(lst) / count) result = [] for i in range(count): #print(i * cols, (i + 1) * cols) result.append(lst[i * cols : (i+1) * cols]) return list(itertools.zip_longest(*result, fillvalue="")) def xmake_column_lists(lst, column_count): count = len(lst) row_count = math.ceil(count / column_count) print(count, column_count, row_count) i = 0 while i < count: i += 1 def columns(K): rows = make_column_lists(K.items.split(), K.n) result = "@table\n" # :lines false :header_line false :leading 1.1 :vmargin false |\n" for row in rows: #print("row:", row) result += " | ".join(row) + " ||\n" result += "table@\n" if K.K_target == "latex": result = f"\\vspace*{{-12pt}}\n{result}" return result