arcology-fastapi/arcology/html.py

101 lines
2.7 KiB
Python

import functools
import pypandoc
@functools.lru_cache(maxsize=128)
def gen_html(input_path: str, extra_cache_key: str = '', input_format: str = 'org'):
return pypandoc.convert_file(input_path, 'html', format='org')
@functools.lru_cache(maxsize=128)
def gen_html_text(input_text: str, extra_cache_key: str = '', input_format: str = 'org'):
return pypandoc.convert_text(input_text, 'html', format='org')
from arcology.parse import print_sexp, parse_sexp
import arcology.arroyo as arroyo
import sqlmodel
import re
from typing import Optional
from arcology.key import id_to_arcology_key, file_to_arcology_key
class HTMLRewriter():
def __init__(self, session):
self.res_404 = 'href="/404?missing={key}" class="dead-link"'
self.session = session
def replace(match):
raise NotImplementedError()
def re(self):
raise NotImplementedError()
def do(self, output_html):
return re.sub(self.re(), self.replace, output_html)
class IDReplacementRewriter(HTMLRewriter):
def replace(self, match):
id = match.group(1)
key = id_to_arcology_key(id, self.session)
if key is None:
return self.res_404.format(key=id)
else:
return 'class="internal" href="{url}"'.format(url=arcology_key_to_url(key))
def re(self):
return r'href="id:([^"]+)"'
class FileReplacementRewriter(HTMLRewriter):
def replace(self, match):
file = match.group(1)
if file is None:
return self.res_404.format(key=file)
key = file_to_arcology_key(file, self.session)
if key is None:
return self.res_404.format(key=file)
else:
return 'class="file" href="{url}"'.format(url=arcology_key_to_url(key))
def re(self):
return r'href="file://([^"]+)"'
class RoamReplacementRewriter(HTMLRewriter):
def replace(self, match):
return self.res_404.format(key=match.group(1)) + ">"
def re(self):
return r'href="roam:([^"]+)">roam:'
class FCClozeReplacementRewriter(HTMLRewriter):
def replace(self, match):
main = match.group(1) or ""
hint = match.group(2) or ""
hint = re.sub(r"</?[^>]+>", "", hint)
return f"<span class='fc-cloze' title='{hint}'>{main}</span>"
def re(self):
return r'{{([^}]+)}{?([^}]+)?}?@[0-9]+}'
def rewrite_html(input_html: str, session: sqlmodel.Session) -> str:
"""
Run a series of replacement functions on the input HTML and return a new string.
"""
output_html = input_html
rewriters = [
IDReplacementRewriter(session),
FileReplacementRewriter(session),
RoamReplacementRewriter(session),
FCClozeReplacementRewriter(session),
]
for rewriter in rewriters:
output_html = rewriter.do(output_html)
return output_html
from arcology.key import ArcologyKey
def arcology_key_to_url(key: ArcologyKey) -> str:
return key.to_url()