6 Commits

Author SHA1 Message Date
e25d97f041 Allow write contexts 2025-09-09 12:35:57 +08:00
e9a7217ba5 Ignore 7z warn 2025-09-09 12:22:52 +08:00
555ade4bce release 0.2.2 2025-09-09 11:58:22 +08:00
b33fb8db41 Add auto release script 2025-09-09 11:57:32 +08:00
00b0af3f9d Add scn special tokens support for fixed formatter 2025-09-08 21:10:52 +08:00
ec6de9a7b9 Support remove zero width space 2025-09-08 19:29:19 +08:00
7 changed files with 127 additions and 3 deletions

View File

@@ -4,6 +4,7 @@ on:
paths-ignore:
- README.md
- '.github/workflows/github-pages.yml'
- '.github/workflows/release.yml'
branches:
- master
pull_request:

View File

@@ -9,6 +9,7 @@ on:
branches: [ "master" ]
paths-ignore:
- '.github/workflows/CI.yml'
- '.github/workflows/release.yml'
- 'doc/**'
- Dockerfile
- docker-compose.yml

67
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,67 @@
name: Build release
on:
release:
types: [published]
permissions:
contents: write
jobs:
build-musl:
runs-on: ubuntu-latest
strategy:
matrix:
arch: [aarch64-unknown-linux-musl, x86_64-unknown-linux-musl]
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up Rust
run: |
rustup update
rustup target add ${{ matrix.arch }}
- name: Download musl toolchain
run: |
arch=${{ matrix.arch }}
arch=${arch/-unknown/}
curl -L "https://github.com/lifegpc/musl-toolchain/releases/download/gcc-9.4/${arch}-x86_64-linux-static.7z" -o musl-toolchain.7z
sudo 7z x musl-toolchain.7z -o./musl-toolchain || true
- name: Build project
run: |
arch=${{ matrix.arch }}
arch=${arch/-unknown/}
export PATH="$PWD/musl-toolchain/bin:$PATH"
export CC="${arch}-cc"
export CXX="${arch}-g++"
export AR="${arch}-ar"
export RUSTFLAGS="-C linker=${CC}"
cargo build --release --target ${{ matrix.arch }}
version=${{ github.event.release.tag_name }}
cd target/${{ matrix.arch }}/release
7z a -mx9 "../../../msg_tool-${version}-${{ matrix.arch }}.zip" "msg_tool"
- name: Upload to release
run: |
version=${{ github.event.release.tag_name }}
gh release upload "${version}" msg_tool-${version}-${{ matrix.arch }}.zip --clobber
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
build-windows:
runs-on: windows-latest
strategy:
matrix:
arch: [aarch64-pc-windows-msvc, x86_64-pc-windows-msvc]
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up Rust
run: |
rustup update
rustup target add ${{ matrix.arch }}
- name: Build project
run: |
cargo build --release --target ${{ matrix.arch }}
cd target/${{ matrix.arch }}/release
7z a -mx9 "../../../msg_tool-${{ github.event.release.tag_name }}-${{ matrix.arch }}.zip" "msg_tool.exe" "msg_tool.pdb"
- name: Upload to release
run: gh release upload "${{ github.event.release.tag_name }}" msg_tool-${{ github.event.release.tag_name }}-${{ matrix.arch }}.zip --clobber
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

4
Cargo.lock generated
View File

@@ -1133,7 +1133,7 @@ dependencies = [
[[package]]
name = "msg_tool"
version = "0.2.1"
version = "0.2.2"
dependencies = [
"anyhow",
"byteorder",
@@ -1170,7 +1170,7 @@ dependencies = [
"url",
"utf16string",
"webp",
"windows-sys 0.60.2",
"windows-sys 0.59.0",
"xml5ever",
"zstd",
]

View File

@@ -1,6 +1,6 @@
[package]
name = "msg_tool"
version = "0.2.1"
version = "0.2.2"
edition = "2024"
repository = "https://github.com/lifegpc/msg-tool"
description = "A command-line tool for exporting, importing, packing, and unpacking script files."

View File

@@ -71,6 +71,16 @@ impl FixedFormatter {
false
}
#[cfg(feature = "kirikiri")]
fn is_scn(&self) -> bool {
matches!(self.typ, Some(ScriptType::KirikiriScn))
}
#[cfg(not(feature = "kirikiri"))]
fn is_scn(&self) -> bool {
false
}
pub fn format(&self, message: &str) -> String {
let mut result = String::new();
let vec: Vec<_> = UnicodeSegmentation::graphemes(message, true).collect();
@@ -235,6 +245,27 @@ impl FixedFormatter {
}
}
if self.is_scn() {
if grapheme == "%" {
is_command = true;
} else if is_command && grapheme == ";" {
is_command = false;
i += 1;
continue;
}
if grapheme == "[" {
is_ruby = true;
is_ruby_rt = true;
i += 1;
continue;
} else if is_ruby && grapheme == "]" {
is_ruby = false;
is_ruby_rt = false;
i += 1;
continue;
}
}
if is_command {
if let Some(ref mut cmd) = last_command {
cmd.push_str(grapheme);
@@ -340,4 +371,14 @@ fn test_format() {
"@re1@re2@b1@t30@w1「当然现在我很幸福哦?因为有你在身边」@n\n「@b1@t38@w1当然现在我很幸福哦?因为有敦也君在身边」"
);
}
#[cfg(feature = "kirikiri")]
{
let scn_formatter =
FixedFormatter::new(3, false, false, false, Some(ScriptType::KirikiriScn));
assert_eq!(
scn_formatter.format("%test;[ruby]测[test]试打断。"),
"%test;[ruby]测[test]试打\n断。"
);
}
}

View File

@@ -58,6 +58,8 @@ impl<'a> M3tParser<'a> {
if line.is_empty() {
continue;
}
// Remove zero-width space characters
let line = line.trim().trim_matches('\u{200b}');
if line.starts_with("") {
let line = line[3..].trim();
if !line.starts_with("NAME:") {
@@ -128,6 +130,8 @@ impl<'a> M3tParser<'a> {
if line.is_empty() {
continue;
}
// Remove zero-width space characters
let line = line.trim().trim_matches('\u{200b}');
if line.starts_with("") {
let line = line[3..].trim();
if line.starts_with("NAME:") {
@@ -204,3 +208,13 @@ impl M3tDumper {
result
}
}
#[test]
fn test_zero_width_space() {
let input = "○ NAME: Example\n\n○ Original message\n\u{200b}● 「」\n\n";
let mut parser = M3tParser::new(input, None);
let messages = parser.parse().unwrap();
assert_eq!(messages.len(), 1);
let map = M3tParser::new(input, None).parse_as_map().unwrap();
assert_eq!(map.len(), 1);
}