2015-12-13 22:21:02 +01:00
using System ;
2017-06-22 21:25:39 +02:00
using System.Linq ;
2015-12-13 22:21:02 +01:00
using System.Web ;
using Orchard.Localization ;
namespace Orchard.Tokens.Providers {
public class TextTokens : ITokenProvider {
2017-06-22 21:25:39 +02:00
private static string [ ] _textChainableTokens ;
2015-12-13 22:21:02 +01:00
public TextTokens ( ) {
T = NullLocalizer . Instance ;
2017-06-22 21:25:39 +02:00
_textChainableTokens = new string [ ] { "Limit" , "Format" , "TrimEnd" , "TrimStart" } ;
2015-12-13 22:21:02 +01:00
}
public Localizer T { get ; set ; }
public void Describe ( DescribeContext context ) {
context . For ( "Text" , T ( "Text" ) , T ( "Tokens for text strings" ) )
. Token ( "Limit:*" , T ( "Limit:<text length>[,<ellipsis>]" ) , T ( "Limit text to specified length and append an optional ellipsis text." ) )
. Token ( "Format:*" , T ( "Format:<text format>" ) , T ( "Optional format specifier (e.g. foo{0}bar)." ) )
. Token ( "TrimEnd:*" , T ( "TrimEnd:<chars|number>" ) , T ( "Trims the specified characters or number of them from the end of the string." ) )
2017-06-22 21:25:39 +02:00
. Token ( "TrimStart:*" , T ( "TrimStart:<chars|number>" ) , T ( "Trims the specified characters or number of them from the beginning of the string." ) )
2015-12-13 22:21:02 +01:00
. Token ( "UrlEncode" , T ( "Url Encode" ) , T ( "Encodes a URL string." ) , "Text" )
. Token ( "HtmlEncode" , T ( "Html Encode" ) , T ( "Encodes an HTML string." ) , "Text" )
. Token ( "JavaScriptEncode" , T ( "JavaScript Encode" ) , T ( "Encodes a JavaScript string." ) , "Text" )
. Token ( "LineEncode" , T ( "Line Encode" ) , T ( "Replaces new lines with <br /> tags." ) , "Text" )
;
}
public void Evaluate ( EvaluateContext context ) {
context . For < String > ( "Text" , ( ) = > "" )
// {Text}
. Token (
token = > token = = String . Empty ? String . Empty : null ,
( token , d ) = > d . ToString ( ) )
// {Text.Limit:<length>[,<ellipsis>]}
. Token (
token = > FilterTokenParam ( "Limit:" , token ) ,
( token , t ) = > Limit ( t , token ) )
2017-06-22 21:25:39 +02:00
. Chain ( FilterChainLimitParam , "Text" , ( token , t ) = > Limit ( t , token ) )
2015-12-13 22:21:02 +01:00
// {Text.Format:<formatstring>}
. Token (
token = > FilterTokenParam ( "Format:" , token ) ,
( token , d ) = > String . Format ( token , d ) )
2017-06-22 21:25:39 +02:00
. Chain ( FilterChainFormatParam , "Text" , ( token , d ) = > String . Format ( token , d ) )
2015-12-13 22:21:02 +01:00
// {Text.TrimEnd:<chars|number>}
. Token ( token = > FilterTokenParam ( "TrimEnd:" , token ) , TrimEnd )
2017-06-22 21:25:39 +02:00
. Chain ( FilterChainTrimEndParam , "Text" , TrimEnd )
// {Text.TrimStart:<chars|number>}
. Token ( token = > FilterTokenParam ( "TrimStart:" , token ) , TrimStart )
. Chain ( FilterChainTrimStartParam , "Text" , TrimStart )
2015-12-13 22:21:02 +01:00
. Token ( "UrlEncode" , HttpUtility . UrlEncode )
. Chain ( "UrlEncode" , "Text" , HttpUtility . UrlEncode )
. Token ( "HtmlEncode" , HttpUtility . HtmlEncode )
. Chain ( "HtmlEncode" , "Text" , HttpUtility . HtmlEncode )
. Token ( "JavaScriptEncode" , HttpUtility . JavaScriptStringEncode )
. Chain ( "JavaScriptEncode" , "Text" , HttpUtility . JavaScriptStringEncode )
2017-04-29 16:13:14 +02:00
. Token ( "LineEncode" , text = > ReplaceNewLineCharacters ( text ) )
. Chain ( "LineEncode" , "Text" , text = > ReplaceNewLineCharacters ( text ) )
2015-12-13 22:21:02 +01:00
;
}
2017-04-29 16:13:14 +02:00
private static string ReplaceNewLineCharacters ( string text ) {
return text
. Replace ( "\r\n" , "<br />" )
. Replace ( "\r" , "<br />" )
. Replace ( "\n" , "<br />" ) ;
}
2017-06-22 21:25:39 +02:00
private Tuple < string , string > FilterChainLimitParam ( string token ) {
return FilterChainParam ( "Limit:" , token ) ;
}
private Tuple < string , string > FilterChainFormatParam ( string token ) {
return FilterChainParam ( "Format:" , token ) ;
}
private Tuple < string , string > FilterChainTrimEndParam ( string token ) {
return FilterChainParam ( "TrimEnd:" , token ) ;
}
private Tuple < string , string > FilterChainTrimStartParam ( string token ) {
return FilterChainParam ( "TrimStart:" , token ) ;
}
2015-12-13 22:21:02 +01:00
private static string FilterTokenParam ( string tokenName , string token ) {
2017-06-22 21:25:39 +02:00
if ( ! token . StartsWith ( tokenName , StringComparison . OrdinalIgnoreCase ) ) return null ;
string tokenPrefix ;
int chainIndex , tokenLength ;
if ( token . IndexOf ( ":" ) = = - 1 ) {
tokenPrefix = token ;
}
else {
tokenPrefix = token . Substring ( 0 , token . IndexOf ( ":" ) ) ;
}
if ( ! _textChainableTokens . Contains ( tokenPrefix , StringComparer . OrdinalIgnoreCase ) ) {
return token . StartsWith ( tokenName , StringComparison . OrdinalIgnoreCase ) ? token . Substring ( tokenName . Length ) : null ;
}
// use ")." as chars combination to discover the end of the parameter
chainIndex = token . IndexOf ( ")." ) + 1 ;
tokenLength = ( tokenPrefix + ":" ) . Length ;
if ( chainIndex = = 0 ) { // ")." has not be found
return token . Substring ( tokenLength ) . Trim ( new char [ ] { '(' , ')' } ) ;
}
if ( ! token . StartsWith ( ( tokenPrefix + ":" ) , StringComparison . OrdinalIgnoreCase ) | | chainIndex < = tokenLength ) {
return null ;
}
return token . Substring ( tokenLength , chainIndex - tokenLength ) . Trim ( new char [ ] { '(' , ')' } ) ;
2015-12-13 22:21:02 +01:00
}
2017-06-22 21:25:39 +02:00
/// <summary>
///
/// </summary>
/// <param name="tokenName">The name of the Token (e.g. "Limit:")</param>
/// <param name="token">The entire Token (e.g. "Limit:(3).TrimStart:4")</param>
/// <returns>Tuple representing the token parameter and next tokens (e.g. for token "Limit:(3).TrimStart:4", first string have to be "3", second one have to be "TrimStart:4")</returns>
private static Tuple < string , string > FilterChainParam ( string tokenName , string token ) {
if ( ! token . StartsWith ( tokenName , StringComparison . OrdinalIgnoreCase ) ) return null ;
string tokenPrefix ;
int chainIndex , tokenLength ;
if ( token . IndexOf ( ":" ) = = - 1 ) {
tokenPrefix = token ;
}
else {
tokenPrefix = token . Substring ( 0 , token . IndexOf ( ":" ) ) ;
}
if ( ! _textChainableTokens . Contains ( tokenPrefix , StringComparer . OrdinalIgnoreCase ) ) {
return new Tuple < string , string > ( token , token ) ;
}
// use ")." as chars combination to discover the end of the parameter
chainIndex = token . IndexOf ( ")." ) + 1 ;
tokenLength = ( tokenPrefix + ":" ) . Length ;
if ( chainIndex = = 0 ) { // ")." has not be found
return new Tuple < string , string > ( token . Substring ( tokenLength ) . Trim ( new char [ ] { '(' , ')' } ) , "" ) ;
}
if ( ! token . StartsWith ( ( tokenPrefix + ":" ) , StringComparison . OrdinalIgnoreCase ) | | chainIndex < = tokenLength ) {
return null ;
}
return new Tuple < string , string > ( token . Substring ( tokenLength , chainIndex - tokenLength ) . Trim ( new char [ ] { '(' , ')' } ) , token . Substring ( chainIndex + 1 ) ) ;
}
private static string TrimStart ( string param , string token ) {
if ( string . IsNullOrEmpty ( param ) ) {
return token ;
}
int n ;
if ( ! int . TryParse ( param , out n ) ) {
return token . TrimStart ( param . ToCharArray ( ) ) ;
}
n = Math . Max ( 0 , n ) ; // prevent negative numbers
return token . Substring ( n ) ;
}
2015-12-13 22:21:02 +01:00
private static string TrimEnd ( string param , string token ) {
if ( String . IsNullOrEmpty ( param ) ) {
return token ;
}
int n ;
if ( ! int . TryParse ( param , out n ) ) {
return token . TrimEnd ( param . ToCharArray ( ) ) ;
}
n = Math . Max ( 0 , n ) ; // prevent negative numbers
return token . Substring ( 0 , token . Length - n ) ;
}
private static string Limit ( string token , string param ) {
2017-04-29 16:13:14 +02:00
if ( String . IsNullOrEmpty ( token ) ) {
2015-12-13 22:21:02 +01:00
return String . Empty ;
}
int index = param . IndexOf ( ',' ) ;
int limit = index = = - 1 ? Int32 . Parse ( param ) : Int32 . Parse ( param . Substring ( 0 , index ) ) ;
if ( token . Length < = limit ) {
// no limit
return token ;
}
if ( index = = - 1 ) {
// no ellipsis
return token . Substring ( 0 , limit ) ;
}
else {
// ellipsis
var ellipsis = param . Substring ( index + 1 ) ;
return token . Substring ( 0 , limit ) + ellipsis ;
}
}
}
2012-08-22 15:43:10 -07:00
}