~aleteoryx/gloss

88cdd4d90224a639f3bac0e0b4d7dc1a6fb1fa38 — Aleteoryx 3 months ago ed42056
inline links, minor fixes
3 files changed, 29 insertions(+), 8 deletions(-)

M gloss.py
M testout/a.html
M testsrc/a.gls
M gloss.py => gloss.py +22 -4
@@ 73,7 73,7 @@ def first_pass(slug, fp):
	blocks = []
	for line in lines:
		if len(line) == 0 and block_type is not None:		# block end
			blocks.append(Block(block_type, [html.escape(block_text)], block_meta))
			blocks.append(Block(block_type, block_text, block_meta))
			block_type = None
			block_text = None
			block_meta = ''


@@ 110,10 110,18 @@ def first_pass(slug, fp):
	return GlsFile(slug, [*names], blocks, see_also)

quote_pat = re.compile("((?:(?!@@)(?!//).)+)(?:@@((?:(?!//).)+))?(?://(.+))?")
link_pat = re.compile("(?<!\\\\)<([^<>|]+)(?:\\|([^>]*))?>(?<!\\\\>)")


### GENERATION ###
	

def link_repl(mat):
	url, name = map(lambda x: x if x is None else html.escape(x.strip()), mat.groups())
	if name is not None and len(name) != 0:
		return f'<a href="{url}">{name}</a>'
	else:
		return f'<a href="{url}">&lt;{url}&gt;</a>'

@dataclass(init=False)
class Indexes:
	by_slug: Dict[str, GlsFile]


@@ 138,6 146,16 @@ 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
		text = block.text
		block.text = []
		while (m := link_pat.search(text)) is not None:
			s,e = m.span()
			block.text.append(text[:s].replace('\\<', '<').replace('\\>', '>'))
			text = text[e:]
			block.text.append((link_repl(m),))
		block.text.append(text)

	blacklist = set()
	for name, pat in idx.names_sorted:	# populate local links
		if name in file.names:		# ...but not to the same file


@@ 162,12 180,12 @@ def gen_inner_html(file, idx):
	
	content = f"<h1>{html.escape(file.names[0])}</h1>"
	for block in file.blocks:		# ok generate the html
		text = ''.join(map(lambda x: x if type(x) == str else x[0], block.text))
		text = ''.join(map(lambda x: html.escape(x) if type(x) == str else x[0], block.text))
		if block.ty == 'para':
			content += f"\n<p>{text}</p>"
		elif block.ty == 'quote':
			sauce, date, url = map(
				lambda x: x if x is None else html.escape(x),
				lambda x: x if x is None else html.escape(x.strip()),
				quote_pat.match(block.meta).groups() )

			content += "\n<div>\n\t<blockquote" + ('' if url is None else f' cite="{url}"') + '>'

M testout/a.html => testout/a.html +4 -3
@@ 9,15 9,16 @@
<h1>The Letter A</h1>
<p>this is a paragraph block. these lines will be folded into one string and ultimately rendered roughly the same in the browser.</p>
<div>
	<blockquote>this is a quote block</blockquote>
	<p>&mdash; <cite>aleteoryx</cite></p>
	<blockquote cite="https://aleteoryx.me">this is a quote block</blockquote>
	<p>&mdash; <cite><a href="https://aleteoryx.me">aleteoryx</a></cite>, 2025</p>
</div>
<p><a href="http://example.com">example page</a></p>
<hr>
<h3>See Also:</h3>
<ul>
	<li><a href="b.html">The Letter B</a></li>
</li>
</main>
<footer>File last modified Thu, 2025-14-40 18:40:06 </footer>
<footer>File last modified Fri, 2025-15-51 00:51:02 </footer>
</body>
</html>

M testsrc/a.gls => testsrc/a.gls +3 -1
@@ 7,7 7,9 @@ string and ultimately rendered roughly
the same in the browser.

> this is a quote block
~aleteoryx
~aleteoryx @@ 2025 // https://aleteoryx.me

<http://example.com|example page>

***
b