add json based arrays and objects

This commit is contained in:
kwaroran
2024-06-19 17:55:55 +09:00
parent 55cb71fefc
commit f335170277

View File

@@ -609,9 +609,9 @@ const matcher = (p1:string,matcherArg:matcherArg) => {
case 'message_unixtime_array':{ case 'message_unixtime_array':{
const selchar = db.characters[get(selectedCharID)] const selchar = db.characters[get(selectedCharID)]
const chat = selchar.chats[selchar.chatPage] const chat = selchar.chats[selchar.chatPage]
return chat.message.map((f) => { return makeArray(chat.message.map((f) => {
return f.time ?? 0 return `${f.time ?? 0}`
}).join('§') }))
} }
case 'unixtime':{ case 'unixtime':{
const now = new Date() const now = new Date()
@@ -760,9 +760,9 @@ const matcher = (p1:string,matcherArg:matcherArg) => {
if(!selchar){ if(!selchar){
return '' return ''
} }
return selchar.emotionImages?.map((f) => { return makeArray(selchar.emotionImages?.map((f) => {
return f[0] return f[0]
})?.join('§') ?? '' })) ?? ''
} }
case 'assetlist':{ case 'assetlist':{
const selchar = db.characters[get(selectedCharID)] const selchar = db.characters[get(selectedCharID)]
@@ -883,13 +883,13 @@ const matcher = (p1:string,matcherArg:matcherArg) => {
return arra[1].replaceAll(arra[2], arra[3]) return arra[1].replaceAll(arra[2], arra[3])
} }
case 'split':{ case 'split':{
return arra[1].split(arra[2]).join('§') return makeArray(arra[1].split(arra[2]))
} }
case 'join':{ case 'join':{
return arra[1].split('§').join(arra[2]) return makeArray(parseArray(arra[1]))
} }
case 'spread':{ case 'spread':{
return arra[1].split('§').join('::') return makeArray(parseArray(arra[1]))
} }
case 'trim':{ case 'trim':{
return arra[1].trim() return arra[1].trim()
@@ -899,7 +899,7 @@ const matcher = (p1:string,matcherArg:matcherArg) => {
} }
case 'arraylength': case 'arraylength':
case 'array_length':{ case 'array_length':{
return arra[1].split('§').length.toString() return parseArray(arra[1]).length.toString()
} }
case 'lower':{ case 'lower':{
return arra[1].toLocaleLowerCase() return arra[1].toLocaleLowerCase()
@@ -932,28 +932,52 @@ const matcher = (p1:string,matcherArg:matcherArg) => {
} }
case 'tonumber':{ case 'tonumber':{
return arra[1].split('').filter((v) => { return makeArray(arra[1].split('').filter((v) => {
return !isNaN(Number(v)) || v === '.' return !isNaN(Number(v)) || v === '.'
}).join('') }))
} }
case 'pow':{ case 'pow':{
return Math.pow(Number(arra[1]), Number(arra[2])).toString() return Math.pow(Number(arra[1]), Number(arra[2])).toString()
} }
case 'arrayelement': case 'arrayelement':
case 'array_element':{ case 'array_element':{
return arra[1].split('§').at(Number(arra[2])) ?? 'null' return parseArray(arra[1]).at(Number(arra[2])) ?? 'null'
} }
case 'dictelement':
case 'dict_element':
case 'objectelement':
case 'object_element':{
return parseDict(arra[1])[arra[2]] ?? 'null'
}
case 'element':
case 'ele':{
try {
const agmts = arra.slice(2)
let current = arra[1]
for(const arg of agmts){
current = JSON.parse(current)[arg]
if(!current){
return 'null'
}
}
return current
} catch (error) {
return 'null'
}
}
case 'arrayshift': case 'arrayshift':
case 'array_shift':{ case 'array_shift':{
const arr = arra[1].split('§') const arr = parseArray(arra[1])
arr.shift() arr.shift()
return arr.join('§') return makeArray(arr)
} }
case 'arraypop': case 'arraypop':
case 'array_pop':{ case 'array_pop':{
const arr = arra[1].split('§') const arr = parseArray(arra[1])
arr.pop() arr.pop()
return arr.join('§') return makeArray(arr)
} }
case 'arraypush': case 'arraypush':
case 'array_push':{ case 'array_push':{
@@ -961,31 +985,60 @@ const matcher = (p1:string,matcherArg:matcherArg) => {
} }
case 'arraysplice': case 'arraysplice':
case 'array_splice':{ case 'array_splice':{
const arr = arra[1].split('§') const arr = parseArray(arra[1])
arr.splice(Number(arra[2]), Number(arra[3]), arra[4]) arr.splice(Number(arra[2]), Number(arra[3]), arra[4])
return arr.join('§') return makeArray(arr)
} }
case 'makearray': case 'makearray':
case 'array': case 'array':
case 'a': case 'a':
case 'make_array':{ case 'make_array':{
return arra.slice(1).join('§') return makeArray(arra.slice(1))
}
case 'makedict':
case 'dict':
case 'd':
case 'make_dict':
case 'makeobject':
case 'object':
case 'o':
case 'make_object':{
//ideas:
// - {{o::key1:value1::key2:value2}} - its confusing for users
// - {{o::key1:value1,key2:value2}} - since comma can break the parser, this is not good
// - {{o::key=value::key2=value2}} - this is good enough I think, just need to escape the equal sign
const sliced = arra.slice(1)
let out = {}
for(let i=0;i<sliced.length;i++){
const current = sliced[i]
const firstEqual = current.indexOf('=')
if(firstEqual === -1){
continue
}
const key = current.substring(0, firstEqual)
const value = current.substring(firstEqual + 1)
out[key] = value ?? 'null'
}
return JSON.stringify(out)
} }
case 'history': case 'history':
case 'messages':{ case 'messages':{
const selchar = db.characters[get(selectedCharID)] const selchar = db.characters[get(selectedCharID)]
const chat = selchar.chats[selchar.chatPage] const chat = selchar.chats[selchar.chatPage]
return chat.message.map((f) => { return makeArray(chat.message.map((f) => {
let data = '' let data = ''
if(arra.includes('role')){ if(arra.includes('role')){
data += f.role + ': ' data += f.role + ': '
} }
data += f.data data += f.data
return data return data
}).join("§\n") }))
} }
case 'range':{ case 'range':{
const arr = arra[1].split('§') const arr = parseArray(arra[1])
const start = arr.length > 1 ? Number(arr[0]) : 0 const start = arr.length > 1 ? Number(arr[0]) : 0
const end = arr.length > 1 ? Number(arr[1]) : Number(arr[0]) const end = arr.length > 1 ? Number(arr[1]) : Number(arr[0])
const step = arr.length > 2 ? Number(arr[2]) : 1 const step = arr.length > 2 ? Number(arr[2]) : 1
@@ -1025,7 +1078,7 @@ const matcher = (p1:string,matcherArg:matcherArg) => {
return (db.enabledModules.includes(moduleId) || enabledChatModules.includes(moduleId)) ? '1' : '0' return (db.enabledModules.includes(moduleId) || enabledChatModules.includes(moduleId)) ? '1' : '0'
} }
case 'filter':{ case 'filter':{
const array = arra[1].split('§') const array = parseArray(arra[1])
const filterTypes = [ const filterTypes = [
'all', 'all',
'nonempty', 'nonempty',
@@ -1035,7 +1088,7 @@ const matcher = (p1:string,matcherArg:matcherArg) => {
if(filterType === -1){ if(filterType === -1){
filterType = 0 filterType = 0
} }
return array.filter((f, i) => { return makeArray(array.filter((f, i) => {
switch(filterType){ switch(filterType){
case 0: case 0:
return f !== '' && i === array.indexOf(f) return f !== '' && i === array.indexOf(f)
@@ -1044,7 +1097,7 @@ const matcher = (p1:string,matcherArg:matcherArg) => {
case 2: case 2:
return i === array.indexOf(f) return i === array.indexOf(f)
} }
}).join('§') }))
} }
} }
} }
@@ -1245,6 +1298,29 @@ const legacyBlockMatcher = (p1:string,matcherArg:matcherArg) => {
type blockMatch = 'ignore'|'parse'|'nothing'|'parse-pure'|'pure'|'each' type blockMatch = 'ignore'|'parse'|'nothing'|'parse-pure'|'pure'|'each'
function parseArray(p1:string):string[]{
try {
const arr = JSON.parse(p1)
if(Array.isArray(arr)){
return arr
}
return p1.split('§')
} catch (error) {
return p1.split('§')
}
}
function parseDict(p1:string):{[key:string]:string}{
try {
return JSON.parse(p1)
} catch (error) {
return {}
}
}
function makeArray(p1:string[]):string{
return JSON.stringify(p1)
}
function blockStartMatcher(p1:string,matcherArg:matcherArg):{type:blockMatch,type2?:string}{ function blockStartMatcher(p1:string,matcherArg:matcherArg):{type:blockMatch,type2?:string}{
if(p1.startsWith('#if') || p1.startsWith('#if_pure ')){ if(p1.startsWith('#if') || p1.startsWith('#if_pure ')){
@@ -1433,7 +1509,7 @@ export function risuChatParser(da:string, arg:{
if(blockType.type === 'each'){ if(blockType.type === 'each'){
const subind = blockType.type2.lastIndexOf(' ') const subind = blockType.type2.lastIndexOf(' ')
const sub = blockType.type2.substring(subind + 1) const sub = blockType.type2.substring(subind + 1)
const array = blockType.type2.substring(0, subind).split('§') const array = parseArray(blockType.type2.substring(0, subind))
let added = '' let added = ''
for(let i = 0;i < array.length;i++){ for(let i = 0;i < array.length;i++){
const res = matchResult.replaceAll(`{{slot::${sub}}}`, array[i]) const res = matchResult.replaceAll(`{{slot::${sub}}}`, array[i])