123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- using System;
- using System.Collections.Generic;
- using System.Globalization;
- using System.Linq;
- using System.Text;
- using XUnity.AutoTranslator.Plugin.Core.Configuration;
- namespace XUnity.AutoTranslator.Plugin.Core.Extensions
- {
- public static class StringExtensions
- {
- private static readonly HashSet<char> Numbers = new HashSet<char>
- {
- '0',
- '1',
- '2',
- '3',
- '4',
- '5',
- '6',
- '7',
- '8',
- '9',
- '0',
- '1',
- '2',
- '3',
- '4',
- '5',
- '6',
- '7',
- '8',
- '9'
- };
- private static readonly HashSet<char> NumbersWithDot = new HashSet<char>
- {
- '0',
- '1',
- '2',
- '3',
- '4',
- '5',
- '6',
- '7',
- '8',
- '9',
- '0',
- '1',
- '2',
- '3',
- '4',
- '5',
- '6',
- '7',
- '8',
- '9',
- '.'
- };
- public static TemplatedString TemplatizeByNumbers( this string str )
- {
- var dict = new Dictionary<string, string>();
- bool isNumber = false;
- StringBuilder carg = null;
- char arg = 'A';
- for( int i = 0 ; i < str.Length ; i++ )
- {
- var c = str[ i ];
- if( isNumber )
- {
- if( NumbersWithDot.Contains( c ) )
- {
- carg.Append( c );
- }
- else
- {
- // end current number
- var variable = carg.ToString();
- var ok = true;
- var c1 = variable[ 0 ];
- if( c1 == '.' )
- {
- if( variable.Length == 1 )
- {
- ok = false;
- }
- else
- {
- var c2 = variable[ 1 ];
- ok = Numbers.Contains( c2 );
- }
- }
- if( ok && !dict.ContainsKey( variable ) )
- {
- dict.Add( variable, "{{" + arg + "}}" );
- arg++;
- }
- carg = null;
- isNumber = false;
- }
- }
- else
- {
- if( NumbersWithDot.Contains( c ) )
- {
- isNumber = true;
- carg = new StringBuilder();
- carg.Append( c );
- }
- }
- }
- if( carg != null )
- {
- // end current number
- var variable = carg.ToString();
- var ok = true;
- var c1 = variable[ 0 ];
- if( c1 == '.' )
- {
- if( variable.Length == 1 )
- {
- ok = false;
- }
- else
- {
- var c2 = variable[ 1 ];
- ok = Numbers.Contains( c2 );
- }
- }
- if( ok && !dict.ContainsKey( variable ) )
- {
- dict.Add( variable, "{{" + arg + "}}" );
- arg++;
- }
- }
- if( dict.Count > 0 )
- {
- foreach( var kvp in dict )
- {
- str = str.Replace( kvp.Key, kvp.Value );
- }
- return new TemplatedString( str, dict.ToDictionary( x => x.Value, x => x.Key ) );
- }
- else
- {
- return null;
- }
- }
- public static string SplitToLines( this string text, int maxStringLength, params char[] splitOnCharacters )
- {
- var sb = new StringBuilder();
- var index = 0;
- while( text.Length > index )
- {
- // start a new line, unless we've just started
- if( index != 0 )
- sb.Append( '\n' );
- // get the next substring, else the rest of the string if remainder is shorter than `maxStringLength`
- var splitAt = index + maxStringLength <= text.Length
- ? text.Substring( index, maxStringLength ).LastIndexOfAny( splitOnCharacters )
- : text.Length - index;
- // if can't find split location, take `maxStringLength` characters
- splitAt = ( splitAt == -1 ) ? maxStringLength : splitAt;
- // add result to collection & increment index
- sb.Append( text.Substring( index, splitAt ).Trim() );
- index += splitAt;
- }
- return sb.ToString();
- }
- public static string RemoveWhitespace( this string text )
- {
- // Japanese whitespace, wtf
- return text.Replace( "\n", "" ).Replace( "\r", "" ).Replace( " ", "" ).Replace( " ", "" );
- }
- public static bool ContainsNumbers( this string text )
- {
- foreach( var c in text )
- {
- if( Numbers.Contains( c ) )
- {
- return true;
- }
- }
- return false;
- }
- public static string UnescapeJson( this string str )
- {
- if( str == null ) return null;
- var builder = new StringBuilder( str );
- bool escapeNext = false;
- for( int i = 0 ; i < builder.Length ; i++ )
- {
- var c = builder[ i ];
- if( escapeNext )
- {
- bool found = true;
- char escapeWith = default( char );
- switch( c )
- {
- case 'b':
- escapeWith = '\b';
- break;
- case 'f':
- escapeWith = '\f';
- break;
- case 'n':
- escapeWith = '\n';
- break;
- case 'r':
- escapeWith = '\r';
- break;
- case 't':
- escapeWith = '\t';
- break;
- case '"':
- escapeWith = '\"';
- break;
- case '\\':
- escapeWith = '\\';
- break;
- case 'u':
- escapeWith = 'u';
- break;
- default:
- found = false;
- break;
- }
- // remove previous char and go one back
- if( found )
- {
- if( escapeWith == 'u' )
- {
- // unicode crap, lets handle the next 4 characters manually
- int code = int.Parse( new string( new char[] { builder[ i + 1 ], builder[ i + 2 ], builder[ i + 3 ], builder[ i + 4 ] } ), NumberStyles.HexNumber );
- var replacingChar = (char)code;
- builder.Remove( --i, 6 );
- builder.Insert( i, replacingChar );
- }
- else
- {
- // found proper escaping
- builder.Remove( --i, 2 );
- builder.Insert( i, escapeWith );
- }
- }
- else
- {
- // dont do anything
- }
- escapeNext = false;
- }
- else if( c == '\\' )
- {
- escapeNext = true;
- }
- }
- return builder.ToString();
- }
- }
- }
|