Forráskód Böngészése

Merge branch 'feature/rich_text' into release/v2.12.0

Scrublord1336 6 éve
szülő
commit
7633b3cf98

+ 1 - 1
src/XUnity.AutoTranslator.Plugin.Core/Parsing/ParserResult.cs

@@ -11,7 +11,7 @@ namespace XUnity.AutoTranslator.Plugin.Core.Parsing
          Arguments = args;
          Arguments = args;
       }
       }
 
 
-      public string OriginalText { get; set; }
+      public string OriginalText { get; private set; }
 
 
       public string Template { get; private set; }
       public string Template { get; private set; }
 
 

+ 114 - 0
src/XUnity.AutoTranslator.Plugin.Core/Parsing/RichTextParser.cs

@@ -0,0 +1,114 @@
+using System.Collections.Generic;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace XUnity.AutoTranslator.Plugin.Core.Parsing
+{
+
+   public class RichTextParser
+   {
+      private static readonly Regex TagRegex = new Regex( "<.*?>", RegexOptions.Compiled );
+      private static readonly HashSet<string> IgnoreTags = new HashSet<string> { "ruby", "group" };
+      private static readonly HashSet<string> KnownTags = new HashSet<string> { "b", "i", "size", "color", "ruby", "em", "sup", "sub", "dash", "space", "group", "u", "strike", "param", "format", "emoji", "speed", "sound" };
+
+      public RichTextParser()
+      {
+
+      }
+
+      public ParserResult Parse( string input )
+      {
+         var matches = TagRegex.Matches( input );
+
+         var accumulation = new StringBuilder();
+         var args = new Dictionary<string, string>();
+         var template = new StringBuilder( input.Length );
+         var offset = 0;
+         var arg = 'A';
+
+         foreach( Match m in matches )
+         {
+            var tag = m.Value;
+            var value = tag.Substring( 1, tag.Length - 2 );
+            bool isEndTag = value.StartsWith( "/" );
+            if( isEndTag )
+            {
+               value = value.Substring( 1, value.Length - 1 );
+            }
+
+            var parts = value.Split( '=' );
+            if( parts.Length == 2 )
+            {
+               value = parts[ 0 ];
+            }
+            var isKnown = KnownTags.Contains( value );
+            var isIgnored = IgnoreTags.Contains( value );
+
+            // add normal text
+            var end = m.Index;
+            var start = offset;
+            var text = input.Substring( start, end - start );
+            offset = end + m.Length;
+
+            // if the tag is not known, we want to include as normal text in the NEXT iteration
+            if( !isKnown )
+            {
+               accumulation.Append( text );
+               accumulation.Append( m.Value );
+            }
+            else
+            {
+               text += accumulation;
+               accumulation.Length = 0;
+
+               if( !string.IsNullOrEmpty( text ) )
+               {
+                  var argument = "{{" + ( arg++ ) + "}}";
+                  args.Add( argument, text );
+                  template.Append( argument );
+               }
+
+               if( !isIgnored )
+               {
+                  template.Append( m.Value );
+               }
+            }
+         }
+
+         // catch any remaining text
+         if( offset < input.Length )
+         {
+            var argument = "{{" + ( arg++ ) + "}}";
+            var text = input.Substring( offset, input.Length - offset );
+            args.Add( argument, text );
+            template.Append( argument );
+         }
+
+
+         var templateString = template.ToString();
+         int idx = -1;
+         while( ( idx = templateString.IndexOf( "}}{{" ) ) != -1 )
+         {
+            var arg1 = templateString[ idx - 1 ];
+            var arg2 = templateString[ idx + 4 ];
+
+            var key1 = "{{" + arg1 + "}}";
+            var key2 = "{{" + arg2 + "}}";
+
+            var text1 = args[ key1 ];
+            var text2 = args[ key2 ];
+
+            var fullText = text1 + text2;
+            var fullKey = key1 + key2;
+            var newKey = "{{" + ( ++arg ) + "}}";
+
+            args.Remove( key1 );
+            args.Remove( key2 );
+            args.Add( newKey, fullText );
+            templateString = templateString.Replace( fullKey, newKey );
+         }
+
+         return new ParserResult( input, templateString, args );
+      }
+   }
+}

+ 0 - 293
src/XUnity.AutoTranslator.Plugin.Core/Parsing/UnityTextParserBase.cs

@@ -1,293 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-
-namespace XUnity.AutoTranslator.Plugin.Core.Parsing
-{
-   public abstract class UnityTextParserBase
-   {
-      private static readonly HashSet<char> ValidTagNameChars = new HashSet<char>
-      {
-         'a', 'b', 'c', 'd','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','x','y','z',
-         'A', 'B', 'C', 'D','E','F','G','H','I','j','K','L','M','N','O','P','Q','R','S','T','U','V','X','Y','Z'
-      };
-      private HashSet<string> _ignored = new HashSet<string>();
-
-      public UnityTextParserBase()
-      {
-
-      }
-
-      protected void AddIgnoredTag( string name )
-      {
-         _ignored.Add( name );
-      }
-
-      public ParserResult Parse( string input )
-      {
-         StringBuilder textSinceLastChange = new StringBuilder();
-
-         StringBuilder template = new StringBuilder();
-         Dictionary<string, string> args = new Dictionary<string, string>();
-         bool ignoringCurrentTag = false;
-         char arg = 'A';
-         Stack<string> tags = new Stack<string>();
-
-         var state = ParsingState.Text;
-         for( int i = 0 ; i < input.Length ; i++ )
-         {
-            var c = input[ i ];
-            if( c != '<' && c != '>' )
-            {
-               textSinceLastChange.Append( c );
-            }
-
-            var previousState = state;
-            switch( previousState )
-            {
-               case ParsingState.Text:
-                  state = ParseText( input, ref i );
-                  break;
-               case ParsingState.NamingStartTag:
-                  state = ParseNamingStartTag( input, ref i );
-                  break;
-               case ParsingState.NamingEndTag:
-                  state = ParseNamingEndTag( input, ref i );
-                  break;
-               case ParsingState.FinishingStartTag:
-                  state = ParseFinishingStartTag( input, ref i );
-                  break;
-               case ParsingState.FinishingEndTag:
-                  state = ParseFinishingEndTag( input, ref i );
-                  break;
-               default:
-                  break;
-            }
-
-            bool stateChanged = state != previousState;
-            if( stateChanged )
-            {
-               // whenever the state changes, we want to add text, potentially
-               string text;
-               if( c == '<' || c == '>' )
-               {
-                  text = textSinceLastChange.ToString();
-                  textSinceLastChange = new StringBuilder();
-               }
-               else
-               {
-                  text = TakeAllButLast( textSinceLastChange );
-               }
-               switch( previousState )
-               {
-                  case ParsingState.Text:
-                     {
-                        if( !string.IsNullOrEmpty( text ) )
-                        {
-                           var key = "{{" + arg + "}}";
-                           arg++;
-
-                           args.Add( key, text );
-                           template.Append( key );
-                        }
-                     }
-                     break;
-                  case ParsingState.NamingStartTag:
-                     {
-                        ignoringCurrentTag = _ignored.Contains( text );
-                        tags.Push( text );
-
-                        if( !ignoringCurrentTag )
-                        {
-                           template.Append( "<" + text );
-                           if( state != ParsingState.FinishingStartTag )
-                           {
-                              template.Append( ">" );
-                           }
-                        }
-                     }
-                     break;
-                  case ParsingState.FinishingStartTag:
-                     {
-                        if( !ignoringCurrentTag )
-                        {
-                           template.Append( text + ">" );
-                        }
-                     }
-                     break;
-                  case ParsingState.NamingEndTag:
-                     {
-                        if( !ignoringCurrentTag )
-                        {
-                           template.Append( "<" + text );
-                        }
-
-                        if( state != ParsingState.FinishingEndTag )
-                        {
-                           if( !ignoringCurrentTag )
-                           {
-                              template.Append( ">" );
-                           }
-
-                           var tag = tags.Pop();
-                           ignoringCurrentTag = tags.Count > 0 && _ignored.Contains( tags.Peek() );
-                        }
-                     }
-                     break;
-                  case ParsingState.FinishingEndTag:
-                     {
-                        if( !ignoringCurrentTag )
-                        {
-                           template.Append( text + ">" );
-                        }
-
-                        var tag = tags.Pop();
-                        ignoringCurrentTag = tags.Count > 0 && _ignored.Contains( tags.Peek() );
-                     }
-                     break;
-               }
-            }
-         }
-
-         if( state == ParsingState.Text )
-         {
-            var text = textSinceLastChange.ToString();
-
-            if( !string.IsNullOrEmpty( text ) )
-            {
-               var key = "{{" + arg + "}}";
-               arg++;
-
-               args.Add( key, text );
-               template.Append( key );
-            }
-         }
-
-         // finally, lets merge some of the arguments together
-         var templateString = template.ToString();
-         int idx = -1;
-         while( ( idx = templateString.IndexOf( "}}{{" ) ) != -1 )
-         {
-            var arg1 = templateString[ idx - 1 ];
-            var arg2 = templateString[ idx + 4 ];
-
-            var key1 = "{{" + arg1 + "}}";
-            var key2 = "{{" + arg2 + "}}";
-
-            var text1 = args[ key1 ];
-            var text2 = args[ key2 ];
-
-            var fullText = text1 + text2;
-            var fullKey = key1 + key2;
-            var newKey = "{{" + ( ++arg ) + "}}";
-
-            args.Remove( key1 );
-            args.Remove( key2 );
-            args.Add( newKey, fullText );
-            templateString = templateString.Replace( fullKey, newKey );
-         }
-
-
-         return new ParserResult( input, templateString, args );
-      }
-
-      private string TakeAllButLast( StringBuilder builder )
-      {
-         if( builder.Length > 0 )
-         {
-            var str = builder.ToString( 0, builder.Length - 1 );
-            builder.Remove( 0, builder.Length - 1 );
-            return str;
-         }
-         return string.Empty;
-      }
-
-      private ParsingState ParseText( string s, ref int i )
-      {
-         if( s[ i ] == '<' )
-         {
-            if( i + 1 < s.Length && s[ i + 1 ] == '/' )
-            {
-               return ParsingState.NamingEndTag;
-            }
-            else
-            {
-               return ParsingState.NamingStartTag;
-            }
-         }
-         else
-         {
-            return ParsingState.Text;
-         }
-      }
-
-      private ParsingState ParseNamingStartTag( string s, ref int i )
-      {
-         if( ValidTagNameChars.Contains( s[ i ] ) )
-         {
-            return ParsingState.NamingStartTag;
-         }
-         else if( s[ i ] == '>' )
-         {
-            // we need to determine if we are inside or outside a tag after this!
-            return ParsingState.Text;
-         }
-         else
-         {
-            return ParsingState.FinishingStartTag;
-         }
-      }
-
-      private ParsingState ParseNamingEndTag( string s, ref int i )
-      {
-         if( ValidTagNameChars.Contains( s[ i ] ) )
-         {
-            return ParsingState.NamingEndTag;
-         }
-         else if( s[ i ] == '>' )
-         {
-            // we need to determine if we are inside or outside a tag after this!
-            return ParsingState.Text;
-         }
-         else
-         {
-            return ParsingState.FinishingEndTag;
-         }
-      }
-
-      private ParsingState ParseFinishingStartTag( string s, ref int i )
-      {
-         if( s[ i ] == '>' )
-         {
-            return ParsingState.Text;
-         }
-         else
-         {
-            return ParsingState.FinishingStartTag;
-         }
-      }
-
-      private ParsingState ParseFinishingEndTag( string s, ref int i )
-      {
-         if( s[ i ] == '>' )
-         {
-            return ParsingState.Text;
-         }
-         else
-         {
-            return ParsingState.FinishingEndTag;
-         }
-      }
-
-      private enum ParsingState
-      {
-         Text,
-         NamingStartTag,
-         NamingEndTag,
-         FinishingStartTag,
-         FinishingEndTag
-      }
-   }
-}

+ 3 - 7
src/XUnity.AutoTranslator.Plugin.Core/Parsing/UnityTextParsers.cs

@@ -8,15 +8,11 @@ namespace XUnity.AutoTranslator.Plugin.Core.Parsing
 {
 {
    public static class UnityTextParsers
    public static class UnityTextParsers
    {
    {
-      private static readonly UtageTextParser UtageTextParser = new UtageTextParser();
+      private static readonly RichTextParser RichTextParser = new RichTextParser();
 
 
-      public static UnityTextParserBase GetTextParserByGameEngine()
+      public static RichTextParser GetTextParserByGameEngine()
       {
       {
-         if( Types.AdvEngine != null )
-         {
-            return UtageTextParser;
-         }
-         return null;
+         return RichTextParser;
       }
       }
    }
    }
 }
 }

+ 0 - 10
src/XUnity.AutoTranslator.Plugin.Core/Parsing/UtageTextParser.cs

@@ -1,10 +0,0 @@
-namespace XUnity.AutoTranslator.Plugin.Core.Parsing
-{
-   public class UtageTextParser : UnityTextParserBase
-   {
-      public UtageTextParser()
-      {
-         AddIgnoredTag( "ruby" );
-      }
-   }
-}