@@ -62,6 +62,20 @@ private static Command BuildRootCommand()
6262 HelpName = "path"
6363 } ;
6464
65+ var strictOption = new Option < bool > ( "--strict" )
66+ {
67+ Description = "Simai转MA2时,解析使用严格模式。不可与 --lax 同时使用。" ,
68+ Arity = ArgumentArity . ZeroOrOne ,
69+ DefaultValueFactory = _ => false
70+ } ;
71+
72+ var laxOption = new Option < bool > ( "--lax" )
73+ {
74+ Description = "Simai转MA2时,解析使用宽松模式。不可与 --strict 同时使用。" ,
75+ Arity = ArgumentArity . ZeroOrOne ,
76+ DefaultValueFactory = _ => false
77+ } ;
78+
6579 var inputArgument = new Argument < string > ( "path" )
6680 {
6781 Description = "可以输入以下几种情况:\n " +
@@ -74,6 +88,8 @@ private static Command BuildRootCommand()
7488
7589 root . Options . Add ( levelsOption ) ;
7690 root . Options . Add ( outputOption ) ;
91+ root . Options . Add ( strictOption ) ;
92+ root . Options . Add ( laxOption ) ;
7793 root . Arguments . Add ( inputArgument ) ;
7894
7995 root . SetAction ( parseResult =>
@@ -82,6 +98,13 @@ private static Command BuildRootCommand()
8298 ?? throw new InvalidOperationException ( "缺少参数 path。" ) ;
8399 var levelsRaw = parseResult . GetValue ( levelsOption ) ;
84100 _outputSpec = OutputSpec . Parse ( parseResult . GetValue ( outputOption ) ) ;
101+
102+ var cliStrict = parseResult . GetValue ( strictOption ) ;
103+ var cliLax = parseResult . GetValue ( laxOption ) ;
104+ if ( cliStrict && cliLax ) throw new ArgumentException ( "不能同时指定 --strict 与 --lax。" ) ;
105+ else if ( cliStrict ) _simaiStrictLevel = SimaiParser . StrictLevelEnum . Strict ;
106+ else if ( cliLax ) _simaiStrictLevel = SimaiParser . StrictLevelEnum . Lax ;
107+
85108 RunConvert ( inputPath , levelsRaw ) ;
86109 } ) ;
87110
@@ -90,6 +113,7 @@ private static Command BuildRootCommand()
90113
91114 /// <summary>由 CLI 在每次 <c>SetAction</c> 入口赋值;转换逻辑只读此字段。</summary>
92115 private static OutputSpec _outputSpec ;
116+ private static SimaiParser . StrictLevelEnum _simaiStrictLevel = SimaiParser . StrictLevelEnum . Normal ;
93117
94118 private enum OutputSinkKind { Default , Stdout , Directory , File }
95119
@@ -256,6 +280,8 @@ private static void ConvertMa2PathsToMaidata(string outputDir, string title, IRe
256280 {
257281 if ( ma2FullPaths . Count == 0 )
258282 throw new ArgumentException ( "未提供任何 .ma2 文件。" ) ;
283+ if ( _simaiStrictLevel != SimaiParser . StrictLevelEnum . Normal )
284+ throw new ArgumentException ( "--strict / --lax 仅适用于 Simai(.txt / maidata)转 MA2,不能用于 MA2 转 Simai。" ) ;
259285
260286 var paths = ma2FullPaths . Select ( Path . GetFullPath ) . Distinct ( StringComparer . OrdinalIgnoreCase ) . ToArray ( ) ;
261287 var levelFilter = string . IsNullOrWhiteSpace ( levelsRaw ) ? null : ParseLevelList ( levelsRaw ) ;
@@ -354,7 +380,7 @@ private static void ConvertMaidata(Maidata maidata, IReadOnlyList<int> selected,
354380 var chartInfo = maidata . Levels [ id ] ;
355381 var bigTouch = id is 2 or 3 ;
356382 var isUtage = IsUtageFromLevelString ( chartInfo . Level ) ;
357- var ma2 = SimaiToMa2 ( chartInfo . Inote , maidata . ClockCount , bigTouch , isUtage ) ;
383+ var ma2 = SimaiToMa2 ( chartInfo . Inote , maidata . ClockCount , bigTouch , isUtage , _simaiStrictLevel ) ;
358384 if ( _outputSpec . Kind == OutputSinkKind . Stdout ) Console . Out . Write ( ma2 ) ;
359385 else File . WriteAllText ( outPath , ma2 , new UTF8Encoding ( encoderShouldEmitUTF8Identifier : false ) ) ;
360386 }
@@ -367,7 +393,7 @@ private static void ConvertPlainSimai(string text, string inputDir, string input
367393 var outPath = _outputSpec . Kind == OutputSinkKind . File ? _outputSpec . FsPath ! : Path . Combine ( baseDir , $ "lv_{ outputLevel } .ma2") ;
368394 var destNote = _outputSpec . Kind == OutputSinkKind . Stdout ? "(标准输出)" : outPath ;
369395 Console . Error . WriteLine ( $ "Simai → MA2: { inputPath } (lv{ outputLevel } ) → { destNote } ") ;
370- var ma2 = SimaiToMa2 ( text ) ;
396+ var ma2 = SimaiToMa2 ( text , strictLevel : _simaiStrictLevel ) ;
371397 if ( _outputSpec . Kind == OutputSinkKind . Stdout ) Console . Out . Write ( ma2 ) ;
372398 else File . WriteAllText ( outPath , ma2 , new UTF8Encoding ( encoderShouldEmitUTF8Identifier : false ) ) ;
373399 }
@@ -395,9 +421,10 @@ private static void ValidateOutputFileExtension(string filePath, string required
395421 throw new ArgumentException ( $ "输出文件扩展名须为「{ requiredExt } 」,当前为「{ ( string . IsNullOrEmpty ( ext ) ? "(无)" : ext ) } 」。") ;
396422 }
397423
398- private static string SimaiToMa2 ( string inote , int clockCount = 4 , bool bigTouch = false , bool isUtage = false )
424+ private static string SimaiToMa2 ( string inote , int clockCount = 4 , bool bigTouch = false , bool isUtage = false ,
425+ SimaiParser . StrictLevelEnum strictLevel = SimaiParser . StrictLevelEnum . Normal )
399426 {
400- var ( chart , parseAlerts ) = new SimaiParser ( bigTouch , clockCount ) . Parse ( inote ) ;
427+ var ( chart , parseAlerts ) = new SimaiParser ( bigTouch , clockCount , strictLevel ) . Parse ( inote ) ;
401428 PrintAlerts ( parseAlerts ) ;
402429 var ( ma2 , genAlerts ) = new MA2Generator ( isUtage ) . Generate ( chart ) ;
403430 PrintAlerts ( genAlerts ) ;
0 commit comments