A run of Unicode code points now needs one pair of carets, not one pair
each: ^9053 53EF 9053^ renders the characters adjacently, and a single
character inside such a run stands for itself. An invalid code point is
an error naming the position that wrote it, rather than an apology
rendered into the finished document; noncharacters are refused alongside
surrogates; and a code point that lands on a Klammertext special is safe
through the re-reads that assemble a document. The character tables now
produce the precomposed form, so a diacritic written as ^a" and one typed
directly are the same text to a search or a copy-paste.
"kdesc -u" describes how to write a Unicode character, with tables of
glyphs beside the codes that produce them. It is new and not yet
complete: it predates the sequence form and the typeface klammer below.
A typeface and a style are no longer both called "font". A typeface is a
family resolved by name; a style code is the one letter naming a type
style. So @document takes :serif_typeface and its siblings, a table takes
:style, captions take :caption_style and :caption_size, the uniform scale
is :text_scale, and the command is "kdesc --typeface". This renames
arguments a document may already use; an old name is a located error
rather than a silent omission.
@typeface sets a passage in another typeface for the length of that
passage:
@typeface Noto Sans Egyptian Hieroglyphs | ^132AA 133CF^ :scale 1.5 @
Writing the klammer is the whole declaration -- the document resolves the
typeface, embeds it in what it produces, and carries its license along.
Two typefaces for scripts no text font covers now ship with Klammertext:
Noto Sans Egyptian Hieroglyphs and Noto Sans Cuneiform. Every typeface in
the distribution now carries its license file.
(from dev 61e598698891)
144 lines
5.1 KiB
Python
144 lines
5.1 KiB
Python
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 = 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"<li>\n{kutil.format_for_paragraphs(e.strip())}\n</li>\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"<i>{s}</i>",
|
|
"b" : f"<b>{s}</b>",
|
|
"t" : f'<span class="monospace">{s}</span>',
|
|
"c" : f'<span class="monospace">{s}</span>',
|
|
"s" : f'<span class="sansserif">{s}</span>'}[self.style]
|
|
result = "\n\n".join([f"<dt>{fontify(term)}</dt>\n<dd>{definition}</dd>"
|
|
for term,definition in self.items])
|
|
result = f"<dl>\n{result}\n</dl>"
|
|
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}"
|
|
# The "\hfill\newline" was to force the description to the next line even if the item was small:
|
|
# result = "\n\n".join([f"\\item[{{{fontify(term)}}}]\\hfill\n\\newline {definition}"
|
|
strut = r"\rule[-8pt]{0pt}{8pt}"
|
|
result = "\n\n".join([f"\\item[{{{fontify(term)}{strut}}}] {definition}"
|
|
for term,definition in self.items])
|
|
result = f"\\begin{{description}}[labelindent=12pt,nosep,itemsep=6pt,parsep=.5\\parskip,style=nextline]\n{result}\n\\end{{description}}"
|
|
return result
|
|
|
|
# Needs to be implemented:
|
|
# def txt(self):
|
|
# return "TXT DEFINITIONS"
|
|
|
|
|
|
class Lines(klammer_base.Klammer_base):
|
|
def __init__(self, K):
|
|
super().__init__(K)
|
|
|
|
def html(self):
|
|
#return " <br/>".join(self.s.strip().split("\n"))
|
|
#return f'<pre style="font-family: var(--serif)">{self.s}</pre>'
|
|
#return f'<pre>{self.s}</pre>'
|
|
result = self.s
|
|
result = re.sub("\n", "<br/>\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 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
|