text: //
  //  NSString+YYAdd.h
  //  YYCategories <https://github.com/ibireme/YYCategories>
  //
  //  Created by ibireme on 13/4/3.
  //  Copyright (c) 2015 ibireme.
  //
  //  This source code is licensed under the MIT-style license found in the
  //  LICENSE file in the root directory of this source tree.
  //
  
  #import <UIKit/UIKit.h>
  
  /**
   Provide hash, encrypt, encode and some common method for 'NSString'.
   */
  @interface NSString (YYAdd)
  
  
  #pragma mark - Drawing
  ///=============================================================================
  /// @name Drawing
  ///=============================================================================
  
  /**
   Returns the size of the string if it were rendered with the specified constraints.
   
   @param font          The font to use for computing the string size.
   
   @param size          The maximum acceptable size for the string. This value is
   used to calculate where line breaks and wrapping would occur.
   
   @param lineBreakMode The line break options for computing the size of the string.
   For a list of possible values, see NSLineBreakMode.
   
   @return              The width and height of the resulting string's bounding box.
   These values may be rounded up to the nearest whole number.
   */
  - (CGSize)sizeForFont:(UIFont *)font size:(CGSize)size mode:(NSLineBreakMode)lineBreakMode;
  
  /**
   Returns the width of the string if it were to be rendered with the specified
   font on a single line.
   
   @param font  The font to use for computing the string width.
   
   @return      The width of the resulting string's bounding box. These values may be
   rounded up to the nearest whole number.
   */
  - (CGFloat)widthForFont:(UIFont *)font;
  
  /**
   Returns the height of the string if it were rendered with the specified constraints.
   
   @param font   The font to use for computing the string size.
   
   @param width  The maximum acceptable width for the string. This value is used
   to calculate where line breaks and wrapping would occur.
   
   @return       The height of the resulting string's bounding box. These values
   may be rounded up to the nearest whole number.
   */
  - (CGFloat)heightForFont:(UIFont *)font width:(CGFloat)width;
  
  
  #pragma mark - Regular Expression
  ///=============================================================================
  /// @name Regular Expression
  ///=============================================================================
  
  /**
   Whether it can match the regular expression
   
   @param regex  The regular expression
   @param options     The matching options to report.
   @return YES if can match the regex; otherwise, NO.
   */
  - (BOOL)matchesRegex:(NSString *)regex options:(NSRegularExpressionOptions)options;
  
  /**
   Match the regular expression, and executes a given block using each object in the matches.
   
   @param regex    The regular expression
   @param options  The matching options to report.
   @param block    The block to apply to elements in the array of matches.
   The block takes four arguments:
       match: The match substring.
       matchRange: The matching options.
       stop: A reference to a Boolean value. The block can set the value
           to YES to stop further processing of the array. The stop
           argument is an out-only argument. You should only ever set
           this Boolean to YES within the Block.
   */
  - (void)enumerateRegexMatches:(NSString *)regex
                        options:(NSRegularExpressionOptions)options
                     usingBlock:(void (^)(NSString *match, NSRange matchRange, BOOL *stop))block;
  
  /**
   Returns a new string containing matching regular expressions replaced with the template string.
   
   @param regex       The regular expression
   @param options     The matching options to report.
   @param replacement The substitution template used when replacing matching instances.
   
   @return A string with matching regular expressions replaced by the template string.
   */
  - (NSString *)stringByReplacingRegex:(NSString *)regex
                               options:(NSRegularExpressionOptions)options
                            withString:(NSString *)replacement;
  
  
  #pragma mark - Emoji
  ///=============================================================================
  /// @name Emoji
  ///=============================================================================
  
  /**
   Whether the receiver contains Apple Emoji (displayed in current version of iOS).
   */
  - (BOOL)containsEmoji;
  
  - (BOOL)containsEmojiForSystemVersion:(float)systemVersion;
  
  
  #pragma mark - Utilities
  ///=============================================================================
  /// @name Utilities
  ///=============================================================================
  
  /**
   Returns a new UUID NSString
   e.g. "D1178E50-2A4D-4F1F-9BD3-F6AAB00E06B1"
   */
  + (NSString *)stringWithUUID;
  
  /**
   Returns a string containing the characters in a given UTF32Char.
   
   @param char32 A UTF-32 character.
   @return A new string, or nil if the character is invalid.
   */
  + (NSString *)stringWithUTF32Char:(UTF32Char)char32;
  
  /**
   Returns a string containing the characters in a given UTF32Char array.
   
   @param char32 An array of UTF-32 character.
   @param length The character count in array.
   @return A new string, or nil if an error occurs.
   */
  + (NSString *)stringWithUTF32Chars:(const UTF32Char *)char32 length:(NSUInteger)length;
  
  /**
   Enumerates the unicode characters (UTF-32) in the specified range of the string.
   
   @param range The range within the string to enumerate substrings.
   @param block The block executed for the enumeration. The block takes four arguments:
      char32: The unicode character.
      range: The range in receiver. If the range.length is 1, the character is in BMP;
          otherwise (range.length is 2) the character is in none-BMP Plane and stored
          by a surrogate pair in the receiver.
      stop: A reference to a Boolean value that the block can use to stop the enumeration 
          by setting *stop = YES; it should not touch *stop otherwise.
   */
  - (void)enumerateUTF32CharInRange:(NSRange)range usingBlock:(void (^)(UTF32Char char32, NSRange range, BOOL *stop))block;
  
  /**
   Trim blank characters (space and newline) in head and tail.
   @return the trimmed string.
   */
  - (NSString *)stringByTrim;
  
  /**
   Add scale modifier to the file name (without path extension),
   From @"name" to @"name@2x".
   
   e.g.
   <table>
   <tr><th>Before     </th><th>After(scale:2)</th></tr>
   <tr><td>"icon"     </td><td>"icon@2x"     </td></tr>
   <tr><td>"icon "    </td><td>"icon @2x"    </td></tr>
   <tr><td>"icon.top" </td><td>"icon.top@2x" </td></tr>
   <tr><td>"/p/name"  </td><td>"/p/name@2x"  </td></tr>
   <tr><td>"/path/"   </td><td>"/path/"      </td></tr>
   </table>
   
   @param scale Resource scale.
   @return String by add scale modifier, or just return if it's not end with file name.
   */
  - (NSString *)stringByAppendingNameScale:(CGFloat)scale;
  
  /**
   Add scale modifier to the file path (with path extension),
   From @"name.png" to @"name@2x.png".
   
   e.g.
   <table>
   <tr><th>Before     </th><th>After(scale:2)</th></tr>
   <tr><td>"icon.png" </td><td>"icon@2x.png" </td></tr>
   <tr><td>"icon..png"</td><td>"icon.@2x.png"</td></tr>
   <tr><td>"icon"     </td><td>"icon@2x"     </td></tr>
   <tr><td>"icon "    </td><td>"icon @2x"    </td></tr>
   <tr><td>"icon."    </td><td>"icon.@2x"    </td></tr>
   <tr><td>"/p/name"  </td><td>"/p/name@2x"  </td></tr>
   <tr><td>"/path/"   </td><td>"/path/"      </td></tr>
   </table>
   
   @param scale Resource scale.
   @return String by add scale modifier, or just return if it's not end with file name.
   */
  - (NSString *)stringByAppendingPathScale:(CGFloat)scale;
  
  /**
   Return the path scale.
   
   e.g.
   <table>
   <tr><th>Path            </th><th>Scale </th></tr>
   <tr><td>"icon.png"      </td><td>1     </td></tr>
   <tr><td>"icon@2x.png"   </td><td>2     </td></tr>
   <tr><td>"icon@2.5x.png" </td><td>2.5   </td></tr>
   <tr><td>"icon@2x"       </td><td>1     </td></tr>
   <tr><td>"icon@2x..png"  </td><td>1     </td></tr>
   <tr><td>"icon@2x.png/"  </td><td>1     </td></tr>
   </table>
   */
  - (CGFloat)pathScale;
  
  /**
   nil, @"", @"  ", @"\n" will Returns NO; otherwise Returns YES.
   */
  - (BOOL)isNotBlank;
  
  /**
   Returns YES if the target string is contained within the receiver.
   @param string A string to test the the receiver.
   
   @discussion Apple has implemented this method in iOS8.
   */
  - (BOOL)containsString:(NSString *)string;
  
  /**
   Returns YES if the target CharacterSet is contained within the receiver.
   @param set  A character set to test the the receiver.
   */
  - (BOOL)containsCharacterSet:(NSCharacterSet *)set;
  
  /**
   Returns NSMakeRange(0, self.length).
   */
  - (NSRange)rangeOfAll;
  
  
  /**
   Create a string from the file in main bundle (similar to [UIImage imageNamed:]).
   
   @param name The file name (in main bundle).
   
   @return A new string create from the file in UTF-8 character encoding.
   */
  + (NSString *)stringNamed:(NSString *)name;
  
  @end
  