add circus special rules to fixed formatter

This commit is contained in:
2025-05-22 08:59:59 +08:00
parent eba514d74f
commit 795832fd3c
3 changed files with 66 additions and 9 deletions

View File

@@ -1,36 +1,79 @@
use crate::types::*;
use unicode_segmentation::UnicodeSegmentation; use unicode_segmentation::UnicodeSegmentation;
const SPACE_STR_LIST: [&str; 2] = [" ", " "];
pub struct FixedFormatter { pub struct FixedFormatter {
length: usize, length: usize,
keep_original: bool, keep_original: bool,
typ: Option<ScriptType>,
} }
impl FixedFormatter { impl FixedFormatter {
pub fn new(length: usize, keep_original: bool) -> Self { pub fn new(length: usize, keep_original: bool, typ: Option<ScriptType>) -> Self {
FixedFormatter { FixedFormatter {
length, length,
keep_original, keep_original,
typ,
} }
} }
fn is_circus(&self) -> bool {
matches!(self.typ, Some(ScriptType::Circus))
}
pub fn format(&self, message: &str) -> String { pub fn format(&self, message: &str) -> String {
let mut result = String::new(); let mut result = String::new();
let vec: Vec<_> = UnicodeSegmentation::graphemes(message, true).collect(); let vec: Vec<_> = UnicodeSegmentation::graphemes(message, true).collect();
let mut current_length = 0; let mut current_length = 0;
let mut is_command = false;
let mut pre_is_lf = false;
let mut is_ruby = false;
let mut is_ruby_rt = false;
for grapheme in vec { for grapheme in vec {
if grapheme == "\n" { if grapheme == "\n" {
if self.keep_original { if self.keep_original {
result.push('\n'); result.push('\n');
current_length = 0; current_length = 0;
} }
pre_is_lf = true;
continue; continue;
} }
if current_length >= self.length { if current_length >= self.length {
result.push('\n'); result.push('\n');
current_length = 0; current_length = 0;
} }
if (current_length == 0 || pre_is_lf) && SPACE_STR_LIST.contains(&grapheme) {
continue;
}
result.push_str(grapheme); result.push_str(grapheme);
current_length += 1; if self.is_circus() {
if grapheme == "@" {
is_command = true;
} else if is_command && grapheme.len() != 1
|| !grapheme
.chars()
.next()
.unwrap_or(' ')
.is_ascii_alphanumeric()
{
is_command = false;
}
if grapheme == "" {
is_ruby = true;
is_ruby_rt = true;
} else if is_ruby && grapheme == "" {
is_ruby_rt = false;
continue;
} else if is_ruby && grapheme == "" {
is_ruby = false;
continue;
}
}
if !is_command && !is_ruby_rt {
current_length += 1;
}
pre_is_lf = false;
} }
return result; return result;
} }
@@ -38,17 +81,31 @@ impl FixedFormatter {
#[test] #[test]
fn test_format() { fn test_format() {
let formatter = FixedFormatter::new(10, false); let formatter = FixedFormatter::new(10, false, None);
let message = "This is a test message.\nThis is another line."; let message = "This is a test message.\nThis is another line.";
let formatted_message = formatter.format(message); let formatted_message = formatter.format(message);
assert_eq!( assert_eq!(
formatted_message, formatted_message,
"This is a \ntest messa\nge.This is\n another l\nine." "This is a \ntest messa\nge.This is\nanother li\nne."
); );
assert_eq!(formatter.format("● This is a test."), "● This is \na test."); assert_eq!(formatter.format("● This is a test."), "● This is \na test.");
let fommater2 = FixedFormatter::new(10, true);
assert_eq!( assert_eq!(
fommater2.format("● Th\nis is a test."), formatter.format("● This is  a test."),
"● This is \na test."
);
let fommater2 = FixedFormatter::new(10, true, None);
assert_eq!(
fommater2.format("● Th\n is is a te st."),
"● Th\nis is a te\nst." "● Th\nis is a te\nst."
); );
let circus_formatter = FixedFormatter::new(10, false, Some(ScriptType::Circus));
assert_eq!(
circus_formatter.format("● @cmd1@cmd2@cmd3中文字数是一\n 二三 四五六七八九十"),
"● @cmd1@cmd2@cmd3中文字数是一二三\n四五六七八九十"
);
assert_eq!(
circus_formatter
.format("● @cmd1@cmd2@cmd3{rubyText/中文}字数是一\n 二三 四五六七八九十"),
"● @cmd1@cmd2@cmd3{rubyText/中文}字数是一二三\n四五六七八九十"
);
} }

View File

@@ -2,13 +2,13 @@ mod fixed;
use crate::types::*; use crate::types::*;
pub fn fmt_message(mes: &mut Vec<Message>, opt: FormatOptions) { pub fn fmt_message(mes: &mut Vec<Message>, opt: FormatOptions, typ: ScriptType) {
match opt { match opt {
FormatOptions::Fixed { FormatOptions::Fixed {
length, length,
keep_original, keep_original,
} => { } => {
let formatter = fixed::FixedFormatter::new(length, keep_original); let formatter = fixed::FixedFormatter::new(length, keep_original, Some(typ));
for message in mes.iter_mut() { for message in mes.iter_mut() {
message.message = formatter.format(&message.message); message.message = formatter.format(&message.message);
} }

View File

@@ -252,7 +252,7 @@ pub fn import_script(
} }
None => {} None => {}
} }
format::fmt_message(&mut mes, fmt); format::fmt_message(&mut mes, fmt, *builder.script_type());
script.import_messages(mes, &patched_f, encoding)?; script.import_messages(mes, &patched_f, encoding)?;
Ok(types::ScriptResult::Ok) Ok(types::ScriptResult::Ok)
} }