101 lines
2.7 KiB
Python
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()
|