latex bot discord
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
extends Node

const laTeXture := preload("./addons/GodoTeX/LaTeXture.cs")


func compile(source: String) -> RegEx:
	var reg := RegEx.new()
	reg.compile(source)
	return reg


func _ready() -> void:
	var bot := DiscordBot.new()
	add_child(bot)
	var file := File.new()
	var err := file.open("res://token", File.READ)
	var token: String
	if err == OK:
		token = file.get_as_text()
	elif OS.has_environment("TOKEN"):
		token = OS.get_environment("TOKEN")
	else:
		push_error("token missing")
	file.close()
	bot.TOKEN = token
	bot.connect("bot_ready", self, "_on_bot_ready")
	bot.connect("message_create", self, "_on_message_create")
	bot.connect("interaction_create", self, "_on_interaction_create")
	bot.login()


func _on_bot_ready(bot: DiscordBot) -> void:
	bot.set_presence({"activity": {"type": "Game", "name": "Printing LaTeX"}})
	var latex_cmd: ApplicationCommand = ApplicationCommand.new() \
	  .set_name("latex") \
	  .add_option(ApplicationCommand.string_option("latex", "The LaTeX to render", { required = true })) \
	  .set_description("Render LaTeX")
	bot.register_command(latex_cmd)
	print("Logged in as " + bot.user.username + "#" + bot.user.discriminator)
	print("Listening on " + str(bot.channels.size()) + " channels and " + str(bot.guilds.size()) + " guilds.")


func _on_message_create(bot: DiscordBot, message: Message, _channel: Dictionary) -> void:
	if message.author.bot:
		return
	var msg: String
	var reg := compile("`{3}(la)?tex([^`]+)`{3}")
	var res := reg.search(message.content)
	if res:
		msg = res.strings[2]
	else:
		var reg2 := compile("!(la)?tex\\s*([\\s\\S]+)")
		var res2 := reg2.search(message.content)
		if !res2:
			return
		msg = res2.strings[2]

	msg = msg.strip_edges()

	if !msg:
		return
		
	var img := latex2img(msg)
	bot.reply(message, "Tex:", {"files": [{"name": "latex.png", "media_type": "image/png", "data": img}]})

func _on_interaction_create(_bot: DiscordBot, interaction: DiscordInteraction) -> void:
	if not interaction.is_command():
		return

	var command_data := interaction.data

	match command_data.name:
		"latex":
			var pay: String = command_data.options[0].value.strip_edges()
			if pay:
				interaction.defer_reply();
				var t := Time.get_ticks_usec()
				var img := latex2img(command_data.options[0].value)
				print_debug("took %.2f seconds" % ((Time.get_ticks_usec() - t) / 1000000.0))
				interaction.edit_reply({"files": [{"content": "", "name": "latex.png", "media_type": "image/png", "data": img}]})
			else:
				interaction.reply({"content": "Bad latex"})
		_:
			interaction.reply({"content": "Invalid command"})
	

func latex2img(latex: String) -> PoolByteArray:
	print_debug("----\n%s\n----" % latex)
	var tex := laTeXture.new()
	tex.LatexExpression = latex
	tex.MathColor = Color.white
	tex.Fill = true
	tex.FontSize = 80
	tex.Render()
	return tex.get_data().save_png_to_buffer()