@@ 39,6 39,7 @@ class Block:
@dataclass
class GlsFile:
slug: str
+ title: str
names: Set[str]
blocks: List[Block]
see_also: Optional[List[str]]
@@ 57,9 58,12 @@ def first_pass(slug, fp):
lines = readlines(fp)
names = set()
+ title = None
for name in lines:
if len(name) == 0 and len(names) != 0: # section end
break
+ if title is None:
+ title = name.strip();
names.add(name.strip())
if len(names) == 0:
@@ 106,11 110,15 @@ def first_pass(slug, fp):
see_also = None
if do_see_also:
see_also = [*filter(len, lines)]
+ elif block_type is not None:
+ blocks.append(Block(block_type, block_text, block_meta))
- return GlsFile(slug, [*names], blocks, see_also)
+ return GlsFile(slug, title, [*names], blocks, see_also)
quote_pat = re.compile("((?:(?!@@)(?!//).)+)(?:@@((?:(?!//).)+))?(?://(.+))?")
link_pat = re.compile("(?<!\\\\)<([^<>|]+)(?:\\|([^>]*))?>(?<!\\\\>)")
+stripped_link_pat = "(?<!\\\\)<[^<>|]+(?:\\|[^>]*)?>(?<!\\\\>)"
+italic_pat = re.compile(f"(?:(?<=\\W)|^)/(?:[^<>/]|{stripped_link_pat})+/(?:(?=\\W)|$)")
### GENERATION ###
@@ 146,15 154,28 @@ class Indexes:
sorted(self.names_sorted, key=lambda x: len(x[0]))
def gen_inner_html(file, idx):
- for block in file.blocks: # populate external links, listify block.text
+ for block in file.blocks: # populate italics+external links, listify block.text
text = block.text
- block.text = []
- while (m := link_pat.search(text)) is not None:
+ working = []
+ while (m := italic_pat.search(text)) is not None:
s,e = m.span()
- block.text.append(text[:s].replace('\\<', '<').replace('\\>', '>'))
+ working.append(text[:s])
+ working.append(('<i>',))
+ working.append(text[s:e])
+ working.append(('</i>',))
text = text[e:]
- block.text.append((link_repl(m),))
- block.text.append(text)
+ working.append(text)
+ block.text = []
+ for text in working:
+ if type(text) != str:
+ block.text.append(text)
+ continue
+ while (m := link_pat.search(text)) is not None:
+ s,e = m.span()
+ block.text.append(text[:s].replace('\\<', '<').replace('\\>', '>'))
+ block.text.append((link_repl(m),))
+ text = text[e:]
+ block.text.append(text)
blacklist = set()
for name, pat in idx.names_sorted: # populate local links
@@ 178,7 199,7 @@ def gen_inner_html(file, idx):
block.text.insert(i, seg[:s])
break
- content = f"<h1>{html.escape(file.names[0])}</h1>"
+ content = f"<h1>{html.escape(file.title)}</h1>"
for block in file.blocks: # ok generate the html
text = ''.join(map(lambda x: html.escape(x) if type(x) == str else x[0], block.text))
if block.ty == 'para':
@@ 201,10 222,22 @@ def gen_inner_html(file, idx):
if file.see_also is not None and len(file.see_also) != 0:
content += "\n<hr>\n<h3>See Also:</h3>\n<ul>"
- for slug in file.see_also:
- name = idx.by_slug[slug].names[0]
- content += f"\n\t<li><a href=\"{html.escape(slug)}.html\">{html.escape(name)}</a></li>"
- content += "\n</li>"
+ for what in file.see_also:
+ if what in idx.by_slug:
+ page = idx.by_slug[what]
+ href = page.slug
+ name = page.title
+ elif what in idx.by_name:
+ page = idx.by_name[what]
+ href = page.slug
+ name = page.title
+ else:
+ if '|' in what:
+ href, name = what.split('|', 1)
+ else:
+ href = name = what
+ content += f"\n\t<li><a href=\"{html.escape(href)}.html\">{html.escape(name)}</a></li>"
+ content += "\n</ul>"
return content
@@ 250,7 283,7 @@ if __name__ == '__main__':
for file in files:
with open(f'{outdir}/{file.slug}.html', 'wt') as fp:
ctx = {
- 'title': html.escape(file.names[0]),
+ 'title': html.escape(file.title),
'slug': html.escape(file.slug),
'body': gen_inner_html(file, indexes),
'modtime': datetime.fromtimestamp(stat(f'{srcdir}/{file.slug}.gls').st_mtime)