diff --git a/package-lock.json b/package-lock.json index 4c74e04..bba36f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -225,9 +225,9 @@ } }, "node_modules/@cloudrac3r/discord-markdown": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/@cloudrac3r/discord-markdown/-/discord-markdown-2.6.7.tgz", - "integrity": "sha512-bWLmBYWaNEDcQfZHDz4jaAxLKA9161ruEnHo3ms6kfRw8uYku/Uz7U1xTmQ2dQF/q1PiuBvM9I37pLiotlQj8A==", + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/@cloudrac3r/discord-markdown/-/discord-markdown-2.6.8.tgz", + "integrity": "sha512-ZrSimHqmLqXR+W3U1n6ge6poAjmQaMzXyWrTkT36znrgKhfuQAYxLBtKTf7m+cmr3VlaDVM2P+iPdSeTeaM0qg==", "license": "MIT", "dependencies": { "simple-markdown": "^0.7.3" @@ -1210,9 +1210,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.19.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.0.tgz", - "integrity": "sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA==", + "version": "22.19.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.1.tgz", + "integrity": "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1713,9 +1713,9 @@ } }, "node_modules/discord-api-types": { - "version": "0.38.32", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.32.tgz", - "integrity": "sha512-UhIqkFuUVwBzejLPPWF18qixYPucMf718RnGh1NxZYNS7czXUmcUsWWkzWR7lRWj5pjfj4LwrnN9McvpfLvGqQ==", + "version": "0.38.33", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.33.tgz", + "integrity": "sha512-oau1V7OzrNX8yNi+DfQpoLZCNCv7cTFmvPKwHfMrA/tewsO6iQKrMTzA7pa3iBSj0fED6NlklJ/1B/cC1kI08Q==", "license": "MIT", "workspaces": [ "scripts/actions/documentation" diff --git a/scripts/text-probability.js b/scripts/text-probability.js new file mode 100644 index 0000000..cc93405 --- /dev/null +++ b/scripts/text-probability.js @@ -0,0 +1,65 @@ +// @ts-check + +const Ty = require("../src/types") +const fs = require("fs") +const domino = require("domino") +const repl = require("repl") + +const pres = (() => { + const pres = [] + for (const file of process.argv.slice(2)) { + const data = JSON.parse(fs.readFileSync(file, "utf8")) + /** @type {Ty.Event.Outer<{msgtype?: string}>[]} */ + const events = data.messages + for (const event of events) { + if (event.type !== "m.room.message" || event.content.msgtype !== "m.text") continue + /** @type {Ty.Event.M_Room_Message} */ // @ts-ignore + const content = event.content + if (content.format !== "org.matrix.custom.html") continue + if (!content.formatted_body) continue + + const document = domino.createDocument(content.formatted_body) + // @ts-ignore + for (const pre of document.querySelectorAll("pre").cache) { + const content = pre.textContent + if (content.length < 100) continue + pres.push(content) + } + } + } + return pres +})() + +// @ts-ignore +global.gc() + +/** @param {string} text */ +function probablyFixedWidthIntended(text) { + // if internal spaces are used, seems like they want a fixed-width font + if (text.match(/[^ ] {3,}[^ ]/)) return true + // if characters from Unicode General_Category "Symbol, other" are used, seems like they're doing ascii art and they want a fixed-width font + if (text.match(/\p{So}/v)) return true + // check start of line indentation + let indents = new Set() + for (const line of text.trimEnd().split("\n")) { + indents.add(line.match(/^ */)?.[0].length || 0) + // if there are more than 3 different indents (counting 0) then it's code + if (indents.size >= 3) return true + } + // if everything is indented then it's code + if (!indents.has(0)) return true + // if there is a high proportion of symbols then it's code (this filter works remarkably well on its own) + if ([...text.matchAll(/[\\`~;+|<>%$@*&"'=(){}[\]_^]|\.[a-zA-Z]|[a-z][A-Z]/g)].length / text.length >= 0.04) return true + return false +} + +Object.assign(repl.start().context, {pres, probablyFixedWidthIntended}) + +/* +if it has a lot of symbols then it's code +if it has >=3 levels of indentation then it's code +if it is all indented then it's code +if it has many spaces in a row in the middle then it's ascii art +if it has many non-latin characters then it's language +-> except if they are ascii art characters e.g. ⣿⣿⡇⢸⣿⠃ then it's ascii art +*/ diff --git a/src/d2m/actions/create-room.js b/src/d2m/actions/create-room.js index ff5782d..61e79f3 100644 --- a/src/d2m/actions/create-room.js +++ b/src/d2m/actions/create-room.js @@ -358,7 +358,7 @@ function assertExistsOrAutocreatable(channel, guildID) { * @returns {Promise} room ID */ async function _syncRoom(channelID, shouldActuallySync) { - /** @ts-ignore @type {DiscordTypes.APIGuildChannel} */ + /** @ts-ignore @type {DiscordTypes.APIGuildTextChannel} */ const channel = discord.channels.get(channelID) assert.ok(channel) const guild = channelToGuild(channel)