From 409a5cff24255bb6eec9746084723d9a103c7cab Mon Sep 17 00:00:00 2001 From: kimpure Date: Sun, 19 Jul 2026 08:23:56 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20add=20=EC=88=98=EA=B3=A0,=20=EB=A0=88?= =?UTF-8?q?=EC=A0=84=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/tts/index.ts | 2 +- packages/utils/saferKorean.ts | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/packages/tts/index.ts b/packages/tts/index.ts index a3256ef..e2349e2 100644 --- a/packages/tts/index.ts +++ b/packages/tts/index.ts @@ -15,7 +15,7 @@ export abstract class TTSModelBase { public ttsify(input: string): string { return saferKorean( input.replace( - /:[^:]+:/g, + /:[a-zA-Z0-9_]+:/g, (text: string): string => TTSModelBase.EMOJI_MAP[text] ?? "이모지", ), ); diff --git a/packages/utils/saferKorean.ts b/packages/utils/saferKorean.ts index c6ca9e2..1bcb831 100644 --- a/packages/utils/saferKorean.ts +++ b/packages/utils/saferKorean.ts @@ -9,6 +9,9 @@ export function processUnsounds(input: string): string { return ( input // Change tailing dots + .replace(/^ *([.,]+) *$/, (_, content: string) => + "쩜".repeat(Math.max(content.length, 3)), + ) .replace(/[.,]+$/, "") .replace(/[.,]{2,}/g, "") .replace(/[.,]\s/g, " ") @@ -36,12 +39,12 @@ export function processCensor(input: string): string { /([\S!?~]+)([!?~]*)/g, (_, content: string, tailSymbol: string) => content + tailSymbol, ) - .replace( - /([흐하해헤혀형][아으앙응앗웅응ㅡ!?.,><~'"/]+)/g, - (content: string) => content[0] ?? "", - ) + .replace(/([흐하해헤혀형][아으앙응앗웅응ㅡ !?.,><~'"/]+)/g, "") .replace(processCensor.StrangeRepeatableRegex, (content: string) => content.substring(0, 3), + ) + .replace(processCensor.StrangeJoinerRegex, (content: string) => + content.substring(0, 2), ); } export namespace processCensor { @@ -51,14 +54,18 @@ export namespace processCensor { "에", "오", "ㅗ", "야", "ㅑ", "읍", "앙", "읏", "웃", "엉", "앗", "엣", "웅", "응", "흐", "해", "헤", "헼", "헥", "하", "형", "혀", "흡", "흑", - "협", "혓", "핫", "헵", "햅", "잇", + "협", "혓", "핫", "헵", "햅", "잇", "ㅇ", "あ", "ア", "う", "お", "ー", "a", "A", "o", "O", "u", "U", ]; export const StrangeRepeatableRegex = new RegExp( - `[${StrangeRepeatable.join("")}][${StrangeRepeatable.join("")}!.,><~'"/]{2,}`, + `[${StrangeRepeatable.join("")}][${StrangeRepeatable.join("")} !.,><~'"/]{2,}`, "g", ); + export const StrangeJoiner = ["아", "으", "앙"]; + export const StrangeJoinerRegex = new RegExp( + `[${StrangeJoiner.join("")}]{2,}`, + ); } // 핵토파스칼, 바, 핵타르 AU (에이커 인치 피트 야드) @@ -104,6 +111,7 @@ export namespace processKorean { ㅇㅃㅅㄹ: "이쁜사랑", ㅇㅈㄹ: "이지랄", ㅈㄹㄴ: "지랄노", + ㄹㅈㄷ: "래전드", ㅁㅇ: "모야", ㅎㅇ: "하이", ㅅㄹ: "싫어", @@ -131,6 +139,7 @@ export namespace processKorean { ㅈㅁ: "잠깐만", ㅈㄴ: "존나", ㄱㄴ: "가능", + ㅅㄱ: "수고", }; export const DoubleMixedChoseongMapRegex = new RegExp( Object.keys(DoubleMixedChoseongMap)