[ADD] Add basic LilyPond support.

Right now, it's using the lily!show command, which might change
(check out #4)
This commit is contained in:
LoaD Accumulator 2023-06-14 13:01:27 +02:00
parent a1b05b883e
commit 60278db59e
No known key found for this signature in database
GPG key ID: 6898757653ABE3E6
7 changed files with 87 additions and 28 deletions

View file

@ -1,8 +1,20 @@
from router import Router
from routes import *
from nio import *
latex_regex = r'((?:\$[^\$]+\$)|(?:\$\$[^\$]+\$\$)|(?:\\\[[^\]]+\\\]))'
tex_router = Router("tex")
lily_router = Router("lily")
def init_routes() -> None:
tex_router.add_route("help", "This very help menu.", route_help)
tex_router.add_route("delete", "Removes a TeX style file.", route_delete)
lily_router.add_route("help", "This very help menu.", route_help)
lily_router.add_route("show", "Shows an in-line LilyPond expression", route_lshow)
# Our message callback. It should be passed through a router.
async def msg_cb(room: MatrixRoom, event: RoomMessageText) -> None:
import latex
@ -18,12 +30,17 @@ async def msg_cb(room: MatrixRoom, event: RoomMessageText) -> None:
import router
args = shlex.split(event.body[4:])
if len(args) >= 1:
await router.handle_command(args[0], room.room_id, event, args[1:])
await tex_router.handle_command(args[0], room.room_id, event, args[1:])
if event.body.startswith("lily!"):
import router
args = shlex.split(event.body[5:])
if len(args) >= 1:
await lily_router.handle_command(args[0], room.room_id, event, args[1:])
for tex in re.findall(latex_regex, event.body, re.M):
try:
filename = latex.render(event.sender, tex)
await utils.send_png(room, filename)
await utils.send_png(room.room_id, filename)
except FileNotFoundError as e:
content = {
"msgtype": "m.text",

View file

@ -29,7 +29,6 @@ def render(user: str, source: str, png: bool = True) -> str:
if f.endswith(".sty"):
base = os.path.join(directory, f[:-4])
pkgs += "\\usepackage{{{base}}}\n ".format(base=base)
print(pkgs)
fmt = template.format(content=source, packages=pkgs)

24
lilypond.py Normal file
View file

@ -0,0 +1,24 @@
template = r"""
\header {{
tagline = ""
}}
{content}
"""
def render(user: str, source: str, png: bool = True) -> str:
import tempfile
import subprocess
import utils
import os
fmt = template.format(content=source)
tmp = tempfile.NamedTemporaryFile(delete=False)
tmp.write(bytes(fmt, encoding="utf8"))
tmp.close()
if png:
subprocess.run(["lilypond", "-d", "preview", "--png", tmp.name], cwd="/tmp")
return tmp.name + ".preview.png"
subprocess.run(["lilypond", "-d", "preview", "--svg", tmp.name], cwd="/tmp")
return tmp.name + "preview.svg"

11
main.py
View file

@ -3,13 +3,13 @@ from nio import *
import asyncio
import utils
async def main() -> None:
import callbacks
import router
import yaml
# Load our config file.
# Load our config file.
config = {}
try:
with open('texlily.yaml', 'r') as conf:
@ -33,8 +33,11 @@ async def main() -> None:
client.access_token = token
client.user_id = user
# Add routes.
callbacks.init_routes()
# TODO: Fix this hot mess before merging onto main.
client.sync(timeout=10000)
await client.sync(timeout=10000)
# Register all of the callbacks
utils.set_client(client)

View file

@ -1,16 +1,19 @@
from nio import RoomMessageText
import typing
routes = {}
helptxt = {}
def add_route(cmd: str, hlp: str, func: typing.Callable) -> None:
if cmd not in routes.keys():
routes[cmd] = func
helptxt[cmd] = hlp
class Router():
def __init__(self, name: str):
self.routes = {}
self.helptxt = {}
self.name = name
async def handle_command(command: str, room: str, event: RoomMessageText, args: list):
import utils
if command in routes.keys():
await routes[command](utils.get_client(), room, event, args)
def add_route(self, cmd: str, hlp: str, func: typing.Callable) -> None:
if cmd not in self.routes:
self.routes[cmd] = func
self.helptxt[cmd] = hlp
async def handle_command(self, command: str, room: str, event: RoomMessageText, args: list):
import utils
if command in self.routes.keys():
await self.routes[command](self, utils.get_client(), room, event, args)

View file

@ -1,17 +1,21 @@
from router import Router
from nio import *
async def route_help(client: Client, room: str, event: RoomMessageText, args: list) -> None:
async def route_help(r: Router, client: Client, room: str, event: RoomMessageText, args: list) -> None:
import router
import utils
txt = "Commands for TeXLily:\n"
for cmd in router.routes.keys():
txt += f"\ttxt!{cmd}: {router.helptxt[cmd]}\n"
print(r)
for cmd in r.routes:
txt += f" {r.name}!{cmd}: {r.helptxt[cmd]}\n"
await utils.send_msg(client, room, txt)
async def route_delete(client: Client, room: str, event: RoomMessageText, args: list) -> None:
async def route_delete(router: Router, client: Client, room: str, event: RoomMessageText, args: list) -> None:
if len(args) == 1:
import utils
import os
@ -26,3 +30,10 @@ async def route_delete(client: Client, room: str, event: RoomMessageText, args:
except FileNotFoundError:
await utils.send_msg(client, room, f"Couldn't delete style {args[0]}")
pass
async def route_lshow(router: Router, client: Client, room: str, event: RoomMessageText, args: list) -> None:
import lilypond
import utils
if len(args) == 1:
file = lilypond.render("", args[0])
await utils.send_png(room, file)

View file

@ -18,6 +18,11 @@ def set_config(c: dict) -> None:
def get_config() -> dict:
return config
async def send_msg(client: Client, room: str, msg: str):
content = {"msgtype": "m.text", "body": msg}
await client.room_send(room, message_type="m.room.message", content=content)
def create_user_dir(user: str) -> str:
import hashlib
import os
@ -33,10 +38,7 @@ def create_user_dir(user: str) -> str:
return os.path.abspath(path)
async def send_png(room: MatrixRoom, filename: str) -> None:
async def send_png(room: str, filename: str) -> None:
import imagesize
import os
basename = os.path.basename(filename)
@ -63,4 +65,4 @@ async def send_png(room: MatrixRoom, filename: str) -> None:
}
file.close()
await client.room_send(room.room_id, message_type="m.room.message", content=content)
await client.room_send(room, message_type="m.room.message", content=content)