willrune
February 12th, 2024, 17:10
I'm posting here to give an idea to other modders before I forget about what work I have put into it and it is lost.
---
In the title "implementation" is in quotes because I am a JavaScript engineer. I don't know LUA or other languages related to Unity. I'm hoping that work on the regular expression (pattern) and basic business logic comes through and is helpful.
Here is a simple, super rough implementation:
(it basically uses and replaces `RegExp.prototype.exec()`
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec
function emptyStringAsUndefined(input) {
if(input === "") {
return undefined
}
return input
}
function parseMood(text) {
const moodRegExp =/^\/mood\u0020+(?:(?<moodDefinition>\(\u0020*(?:(?<language>.*);\u0020*)?(?<mood>.*)\u0020*\)\u0020*))?(?<message>.*)/
const result = moodRegExp.exec(text)
if (result == null) {
// use `null` for both null and undefined
return null
}
const { groups } = result
const moodDefinition = emptyStringAsUndefined(groups.moodDefinition)
const language = emptyStringAsUndefined(groups.language)
let mood = emptyStringAsUndefined(groups.mood)
let message = emptyStringAsUndefined(groups.message)
if (
typeof language === 'undefined' &&
typeof mood === 'undefined' &&
typeof moodDefinition === 'string' &&
moodDefinition.trim() !== ""
) {
// Mood can be parenthesis consisting only of whitespace
mood = moodDefinition.trimEnd()
}
if (
typeof message === 'undefined' ||
(typeof message === 'string' && message.trim() === '')
) {
// consider messages made up of only whitespace to not be a match. It
// can not be parsed or processed any further
return null
}
if (typeof language === 'undefined' && typeof mood === 'undefined') {
if (typeof message === 'string') {
const trimmedMessage = message.trimStart()
const firstSpaceIndex = trimmedMessage.indexOf(" ")
if(firstSpaceIndex === -1) {
// if there is no message after assuming the first word is the
// mood, then consider it not to be a match
return null
}
const newMood = trimmedMessage.slice(0, firstSpaceIndex)
const newMessage = trimmedMessage.slice(firstSpaceIndex + 1)
if (newMessage === '') {
// if the resulting message is empty, then it is considered not
// to be a match
return null
}
mood = newMood
message = newMessage
}
}
return {
groups: {
...groups,
// Consider an empty string to be the same as undefined to simplify
// consuming code.
language,
message,
mood,
moodDefinition
}
}
}
I imagine a real implementation parses a command first then sends the rest of the line to another parser based on what it finds. The use of null and undefined could be more consistent. There are a number of ways this can be improved.
/mood ([language]; [mood]) <message>
More to come as I have exceeded the character limit for a single post.
---
I have seen Zacchaeus's post regarding Feature Requests.
https://www.fantasygrounds.com/forums/showthread.php?67271-Feature-Requests
Idea informer appears to lack the formatting capabilities that I need to communicate what I want. I generally don't like having multiple credentials for the same community, even though I can appreciate it as a lower barrier to entry and better than nothing.
I'm tired because of searching for a new job, fighting a bad mouse infestation, and a few other things going on. Once things get better I can see about properly using idea informer or looking at the tutorials.
I can see that there are some tutorials in this forum. I am waiting for the caffeine to kick in. I have not yet found the part describing how to create new commands or modify existing ones. I'll keep digging after this post.
---
In the title "implementation" is in quotes because I am a JavaScript engineer. I don't know LUA or other languages related to Unity. I'm hoping that work on the regular expression (pattern) and basic business logic comes through and is helpful.
Here is a simple, super rough implementation:
(it basically uses and replaces `RegExp.prototype.exec()`
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec
function emptyStringAsUndefined(input) {
if(input === "") {
return undefined
}
return input
}
function parseMood(text) {
const moodRegExp =/^\/mood\u0020+(?:(?<moodDefinition>\(\u0020*(?:(?<language>.*);\u0020*)?(?<mood>.*)\u0020*\)\u0020*))?(?<message>.*)/
const result = moodRegExp.exec(text)
if (result == null) {
// use `null` for both null and undefined
return null
}
const { groups } = result
const moodDefinition = emptyStringAsUndefined(groups.moodDefinition)
const language = emptyStringAsUndefined(groups.language)
let mood = emptyStringAsUndefined(groups.mood)
let message = emptyStringAsUndefined(groups.message)
if (
typeof language === 'undefined' &&
typeof mood === 'undefined' &&
typeof moodDefinition === 'string' &&
moodDefinition.trim() !== ""
) {
// Mood can be parenthesis consisting only of whitespace
mood = moodDefinition.trimEnd()
}
if (
typeof message === 'undefined' ||
(typeof message === 'string' && message.trim() === '')
) {
// consider messages made up of only whitespace to not be a match. It
// can not be parsed or processed any further
return null
}
if (typeof language === 'undefined' && typeof mood === 'undefined') {
if (typeof message === 'string') {
const trimmedMessage = message.trimStart()
const firstSpaceIndex = trimmedMessage.indexOf(" ")
if(firstSpaceIndex === -1) {
// if there is no message after assuming the first word is the
// mood, then consider it not to be a match
return null
}
const newMood = trimmedMessage.slice(0, firstSpaceIndex)
const newMessage = trimmedMessage.slice(firstSpaceIndex + 1)
if (newMessage === '') {
// if the resulting message is empty, then it is considered not
// to be a match
return null
}
mood = newMood
message = newMessage
}
}
return {
groups: {
...groups,
// Consider an empty string to be the same as undefined to simplify
// consuming code.
language,
message,
mood,
moodDefinition
}
}
}
I imagine a real implementation parses a command first then sends the rest of the line to another parser based on what it finds. The use of null and undefined could be more consistent. There are a number of ways this can be improved.
/mood ([language]; [mood]) <message>
More to come as I have exceeded the character limit for a single post.
---
I have seen Zacchaeus's post regarding Feature Requests.
https://www.fantasygrounds.com/forums/showthread.php?67271-Feature-Requests
Idea informer appears to lack the formatting capabilities that I need to communicate what I want. I generally don't like having multiple credentials for the same community, even though I can appreciate it as a lower barrier to entry and better than nothing.
I'm tired because of searching for a new job, fighting a bad mouse infestation, and a few other things going on. Once things get better I can see about properly using idea informer or looking at the tutorials.
I can see that there are some tutorials in this forum. I am waiting for the caffeine to kick in. I have not yet found the part describing how to create new commands or modify existing ones. I'll keep digging after this post.