Rename Namespace
I made the mustache namespace upper case. An easy find/replace will fix this for most projects. I bumped the version up to a minor release anyway.
This commit is contained in:
parent
50a80f42ad
commit
22e0cb4c2a
|
@ -4,7 +4,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace mustache.test
|
||||
namespace Mustache.Test
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests the FormatParser class.
|
||||
|
|
|
@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
|||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("0.0.7.2")]
|
||||
[assembly: AssemblyFileVersion("0.0.7.2")]
|
||||
[assembly: AssemblyVersion("0.1.0.0")]
|
||||
[assembly: AssemblyFileVersion("0.1.0.0")]
|
||||
|
|
|
@ -1,63 +1,63 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>
|
||||
</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{7F607362-0680-4751-B1DC-621219294AE3}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>mustache.test</RootNamespace>
|
||||
<AssemblyName>mustache-sharp.test</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
|
||||
<Visible>False</Visible>
|
||||
</CodeAnalysisDependentAssemblyPaths>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="FormatCompilerTester.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\mustache-sharp\mustache-sharp.csproj">
|
||||
<Project>{D71B378F-A4BA-4263-A4F0-07A49A0C528D}</Project>
|
||||
<Name>mustache-sharp</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>
|
||||
</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{7F607362-0680-4751-B1DC-621219294AE3}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Mustache.Test</RootNamespace>
|
||||
<AssemblyName>mustache-sharp.test</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
|
||||
<Visible>False</Visible>
|
||||
</CodeAnalysisDependentAssemblyPaths>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="FormatCompilerTester.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\mustache-sharp\mustache-sharp.csproj">
|
||||
<Project>{D71B378F-A4BA-4263-A4F0-07A49A0C528D}</Project>
|
||||
<Name>mustache-sharp</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -2,7 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Associates parameters to their argument values.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Builds text by combining the output of other generators.
|
||||
|
|
|
@ -3,7 +3,7 @@ using System.Collections;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a tag that conditionally prints its content.
|
||||
|
|
|
@ -1,38 +1,38 @@
|
|||
using System;
|
||||
|
||||
namespace mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a tag that can contain inner text.
|
||||
/// </summary>
|
||||
public abstract class ContentTagDefinition : TagDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a ContentTagDefinition.
|
||||
/// </summary>
|
||||
/// <param name="tagName">The name of the tag being defined.</param>
|
||||
protected ContentTagDefinition(string tagName)
|
||||
: base(tagName)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a ContentTagDefinition.
|
||||
/// </summary>
|
||||
/// <param name="tagName">The name of the tag being defined.</param>
|
||||
/// <param name="isBuiltin">Specifies whether the tag is a built-in tag.</param>
|
||||
internal ContentTagDefinition(string tagName, bool isBuiltin)
|
||||
: base(tagName, isBuiltin)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the tag can have content.
|
||||
/// </summary>
|
||||
/// <returns>True if the tag can have a body; otherwise, false.</returns>
|
||||
protected override bool GetHasContent()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a tag that can contain inner text.
|
||||
/// </summary>
|
||||
public abstract class ContentTagDefinition : TagDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a ContentTagDefinition.
|
||||
/// </summary>
|
||||
/// <param name="tagName">The name of the tag being defined.</param>
|
||||
protected ContentTagDefinition(string tagName)
|
||||
: base(tagName)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a ContentTagDefinition.
|
||||
/// </summary>
|
||||
/// <param name="tagName">The name of the tag being defined.</param>
|
||||
/// <param name="isBuiltin">Specifies whether the tag is a built-in tag.</param>
|
||||
internal ContentTagDefinition(string tagName, bool isBuiltin)
|
||||
: base(tagName, isBuiltin)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the tag can have content.
|
||||
/// </summary>
|
||||
/// <returns>True if the tag can have a body; otherwise, false.</returns>
|
||||
protected override bool GetHasContent()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a context within a template.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information describing a parameter that creates a new context.
|
||||
|
|
|
@ -3,7 +3,7 @@ using System.Collections;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a tag that can iterate over a collection of items and render
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a tag that conditionally renders its content if preceding if and elif tags fail.
|
||||
/// </summary>
|
||||
internal sealed class ElifTagDefinition : ConditionTagDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of an ElifTagDefinition.
|
||||
/// </summary>
|
||||
public ElifTagDefinition()
|
||||
: base("elif")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the tag only exists within the scope of its parent.
|
||||
/// </summary>
|
||||
protected override bool GetIsContextSensitive()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tags that indicate the end of the current tags context.
|
||||
/// </summary>
|
||||
protected override IEnumerable<string> GetClosingTags()
|
||||
{
|
||||
return new string[] { "if" };
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a tag that conditionally renders its content if preceding if and elif tags fail.
|
||||
/// </summary>
|
||||
internal sealed class ElifTagDefinition : ConditionTagDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of an ElifTagDefinition.
|
||||
/// </summary>
|
||||
public ElifTagDefinition()
|
||||
: base("elif")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the tag only exists within the scope of its parent.
|
||||
/// </summary>
|
||||
protected override bool GetIsContextSensitive()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tags that indicate the end of the current tags context.
|
||||
/// </summary>
|
||||
protected override IEnumerable<string> GetClosingTags()
|
||||
{
|
||||
return new string[] { "if" };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a tag that renders its content if all preceding if and elif tags.
|
||||
|
|
|
@ -3,9 +3,9 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using mustache.Properties;
|
||||
using Mustache.Properties;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Parses a format string and returns a text generator.
|
||||
|
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Globalization;
|
||||
using System.IO;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates text by substituting an object's values for placeholders.
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Applies the values of an object to the format plan, generating a string.
|
||||
/// </summary>
|
||||
internal interface IGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates the text when applying the format plan.
|
||||
/// </summary>
|
||||
/// <param name="scope">The current lexical scope of the keys.</param>
|
||||
/// <param name="writer">The text writer to send all text to.</param>
|
||||
/// <returns>The generated text.</returns>
|
||||
void GetText(KeyScope scope, TextWriter writer);
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Applies the values of an object to the format plan, generating a string.
|
||||
/// </summary>
|
||||
internal interface IGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates the text when applying the format plan.
|
||||
/// </summary>
|
||||
/// <param name="scope">The current lexical scope of the keys.</param>
|
||||
/// <param name="writer">The text writer to send all text to.</param>
|
||||
/// <returns>The generated text.</returns>
|
||||
void GetText(KeyScope scope, TextWriter writer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
using System;
|
||||
|
||||
namespace mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a tag that renders its content depending on the truthyness
|
||||
/// of its argument, with optional elif and else nested tags.
|
||||
/// </summary>
|
||||
internal sealed class IfTagDefinition : ConditionTagDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a IfTagDefinition.
|
||||
/// </summary>
|
||||
public IfTagDefinition()
|
||||
: base("if")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the tag only exists within the scope of its parent.
|
||||
/// </summary>
|
||||
protected override bool GetIsContextSensitive()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a tag that renders its content depending on the truthyness
|
||||
/// of its argument, with optional elif and else nested tags.
|
||||
/// </summary>
|
||||
internal sealed class IfTagDefinition : ConditionTagDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a IfTagDefinition.
|
||||
/// </summary>
|
||||
public IfTagDefinition()
|
||||
: base("if")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the tag only exists within the scope of its parent.
|
||||
/// </summary>
|
||||
protected override bool GetIsContextSensitive()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates the text for a tag that only exists on a single line.
|
||||
/// </summary>
|
||||
internal sealed class InlineGenerator : IGenerator
|
||||
{
|
||||
private readonly TagDefinition _definition;
|
||||
private readonly ArgumentCollection _arguments;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of an InlineGenerator.
|
||||
/// </summary>
|
||||
/// <param name="definition">The tag to render the text for.</param>
|
||||
/// <param name="arguments">The arguments passed to the tag.</param>
|
||||
public InlineGenerator(TagDefinition definition, ArgumentCollection arguments)
|
||||
{
|
||||
_definition = definition;
|
||||
_arguments = arguments;
|
||||
}
|
||||
|
||||
void IGenerator.GetText(KeyScope scope, TextWriter writer)
|
||||
{
|
||||
Dictionary<string, object> arguments = _arguments.GetArguments(scope);
|
||||
_definition.GetText(writer, arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates the text for a tag that only exists on a single line.
|
||||
/// </summary>
|
||||
internal sealed class InlineGenerator : IGenerator
|
||||
{
|
||||
private readonly TagDefinition _definition;
|
||||
private readonly ArgumentCollection _arguments;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of an InlineGenerator.
|
||||
/// </summary>
|
||||
/// <param name="definition">The tag to render the text for.</param>
|
||||
/// <param name="arguments">The arguments passed to the tag.</param>
|
||||
public InlineGenerator(TagDefinition definition, ArgumentCollection arguments)
|
||||
{
|
||||
_definition = definition;
|
||||
_arguments = arguments;
|
||||
}
|
||||
|
||||
void IGenerator.GetText(KeyScope scope, TextWriter writer)
|
||||
{
|
||||
Dictionary<string, object> arguments = _arguments.GetArguments(scope);
|
||||
_definition.GetText(writer, arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a tag that cannot contain inner text.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds the information about a key that was found.
|
||||
|
|
|
@ -1,51 +1,51 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Substitutes a key placeholder with the textual representation of the associated object.
|
||||
/// </summary>
|
||||
internal sealed class KeyGenerator : IGenerator
|
||||
{
|
||||
private readonly string _key;
|
||||
private readonly string _format;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a KeyGenerator.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to substitute with its value.</param>
|
||||
/// <param name="alignment">The alignment specifier.</param>
|
||||
/// <param name="formatting">The format specifier.</param>
|
||||
public KeyGenerator(string key, string alignment, string formatting)
|
||||
{
|
||||
_key = key;
|
||||
_format = getFormat(alignment, formatting);
|
||||
}
|
||||
|
||||
private static string getFormat(string alignment, string formatting)
|
||||
{
|
||||
StringBuilder formatBuilder = new StringBuilder();
|
||||
formatBuilder.Append("{0");
|
||||
if (!String.IsNullOrWhiteSpace(alignment))
|
||||
{
|
||||
formatBuilder.Append(",");
|
||||
formatBuilder.Append(alignment.TrimStart('+'));
|
||||
}
|
||||
if (!String.IsNullOrWhiteSpace(formatting))
|
||||
{
|
||||
formatBuilder.Append(":");
|
||||
formatBuilder.Append(formatting);
|
||||
}
|
||||
formatBuilder.Append("}");
|
||||
return formatBuilder.ToString();
|
||||
}
|
||||
|
||||
void IGenerator.GetText(KeyScope scope, TextWriter writer)
|
||||
{
|
||||
object value = scope.Find(_key);
|
||||
writer.Write(_format, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Substitutes a key placeholder with the textual representation of the associated object.
|
||||
/// </summary>
|
||||
internal sealed class KeyGenerator : IGenerator
|
||||
{
|
||||
private readonly string _key;
|
||||
private readonly string _format;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a KeyGenerator.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to substitute with its value.</param>
|
||||
/// <param name="alignment">The alignment specifier.</param>
|
||||
/// <param name="formatting">The format specifier.</param>
|
||||
public KeyGenerator(string key, string alignment, string formatting)
|
||||
{
|
||||
_key = key;
|
||||
_format = getFormat(alignment, formatting);
|
||||
}
|
||||
|
||||
private static string getFormat(string alignment, string formatting)
|
||||
{
|
||||
StringBuilder formatBuilder = new StringBuilder();
|
||||
formatBuilder.Append("{0");
|
||||
if (!String.IsNullOrWhiteSpace(alignment))
|
||||
{
|
||||
formatBuilder.Append(",");
|
||||
formatBuilder.Append(alignment.TrimStart('+'));
|
||||
}
|
||||
if (!String.IsNullOrWhiteSpace(formatting))
|
||||
{
|
||||
formatBuilder.Append(":");
|
||||
formatBuilder.Append(formatting);
|
||||
}
|
||||
formatBuilder.Append("}");
|
||||
return formatBuilder.ToString();
|
||||
}
|
||||
|
||||
void IGenerator.GetText(KeyScope scope, TextWriter writer)
|
||||
{
|
||||
object value = scope.Find(_key);
|
||||
writer.Write(_format, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds the information needed to handle a missing key.
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using mustache.Properties;
|
||||
using Mustache.Properties;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a scope of keys.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a pseudo tag that wraps the entire content of a format string.
|
||||
|
|
|
@ -1,49 +1,49 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds the objects to use when processing a child context of another tag.
|
||||
/// </summary>
|
||||
public sealed class NestedContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a NestedContext.
|
||||
/// </summary>
|
||||
public NestedContext()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the writer to use when generating the child context.
|
||||
/// </summary>
|
||||
/// <remarks>Setting the writer to null will indicate that the tag's writer should be used.</remarks>
|
||||
public TextWriter Writer
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the text sent to the returned writer needs to be added
|
||||
/// to the parent tag's writer. This should be false if the parent writer is
|
||||
/// being returned or is being wrapped.
|
||||
/// </summary>
|
||||
public bool WriterNeedsConsidated
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the scope to use when generating the child context.
|
||||
/// </summary>
|
||||
/// <remarks>Setting the scope to null will indicate that the current scope should be used.</remarks>
|
||||
public KeyScope KeyScope
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds the objects to use when processing a child context of another tag.
|
||||
/// </summary>
|
||||
public sealed class NestedContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a NestedContext.
|
||||
/// </summary>
|
||||
public NestedContext()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the writer to use when generating the child context.
|
||||
/// </summary>
|
||||
/// <remarks>Setting the writer to null will indicate that the tag's writer should be used.</remarks>
|
||||
public TextWriter Writer
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the text sent to the returned writer needs to be added
|
||||
/// to the parent tag's writer. This should be false if the parent writer is
|
||||
/// being returned or is being wrapped.
|
||||
/// </summary>
|
||||
public bool WriterNeedsConsidated
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the scope to use when generating the child context.
|
||||
/// </summary>
|
||||
/// <remarks>Setting the scope to null will indicate that the current scope should be used.</remarks>
|
||||
public KeyScope KeyScope
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using mustache.Properties;
|
||||
using Mustache.Properties;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds the information descibing a key that is found in a template.
|
||||
|
|
|
@ -34,6 +34,6 @@ using System.Runtime.CompilerServices;
|
|||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.0.7.2")]
|
||||
[assembly: AssemblyFileVersion("0.0.7.2")]
|
||||
[assembly: AssemblyVersion("0.1.0.0")]
|
||||
[assembly: AssemblyFileVersion("0.1.0.0")]
|
||||
[assembly: InternalsVisibleTo("mustache-sharp.test")]
|
|
@ -1,135 +1,135 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.296
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace mustache.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("mustache.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to An attempt was made to define a parameter with a null or an invalid identifier..
|
||||
/// </summary>
|
||||
internal static string BlankParameterName {
|
||||
get {
|
||||
return ResourceManager.GetString("BlankParameterName", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to An attempt was made to define a tag with a null or an invalid identifier..
|
||||
/// </summary>
|
||||
internal static string BlankTagName {
|
||||
get {
|
||||
return ResourceManager.GetString("BlankTagName", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to A parameter with the same name already exists within the tag..
|
||||
/// </summary>
|
||||
internal static string DuplicateParameter {
|
||||
get {
|
||||
return ResourceManager.GetString("DuplicateParameter", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The {0} tag has already been registered..
|
||||
/// </summary>
|
||||
internal static string DuplicateTagDefinition {
|
||||
get {
|
||||
return ResourceManager.GetString("DuplicateTagDefinition", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The key {0} could not be found..
|
||||
/// </summary>
|
||||
internal static string KeyNotFound {
|
||||
get {
|
||||
return ResourceManager.GetString("KeyNotFound", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Expected a matching {0} tag but none was found..
|
||||
/// </summary>
|
||||
internal static string MissingClosingTag {
|
||||
get {
|
||||
return ResourceManager.GetString("MissingClosingTag", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Encountered an unknown tag. It was either not registered or exists in a different context..
|
||||
/// </summary>
|
||||
internal static string UnknownTag {
|
||||
get {
|
||||
return ResourceManager.GetString("UnknownTag", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The wrong number of arguments were passed to an {0} tag..
|
||||
/// </summary>
|
||||
internal static string WrongNumberOfArguments {
|
||||
get {
|
||||
return ResourceManager.GetString("WrongNumberOfArguments", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.296
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Mustache.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Mustache.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to An attempt was made to define a parameter with a null or an invalid identifier..
|
||||
/// </summary>
|
||||
internal static string BlankParameterName {
|
||||
get {
|
||||
return ResourceManager.GetString("BlankParameterName", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to An attempt was made to define a tag with a null or an invalid identifier..
|
||||
/// </summary>
|
||||
internal static string BlankTagName {
|
||||
get {
|
||||
return ResourceManager.GetString("BlankTagName", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to A parameter with the same name already exists within the tag..
|
||||
/// </summary>
|
||||
internal static string DuplicateParameter {
|
||||
get {
|
||||
return ResourceManager.GetString("DuplicateParameter", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The {0} tag has already been registered..
|
||||
/// </summary>
|
||||
internal static string DuplicateTagDefinition {
|
||||
get {
|
||||
return ResourceManager.GetString("DuplicateTagDefinition", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The key {0} could not be found..
|
||||
/// </summary>
|
||||
internal static string KeyNotFound {
|
||||
get {
|
||||
return ResourceManager.GetString("KeyNotFound", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Expected a matching {0} tag but none was found..
|
||||
/// </summary>
|
||||
internal static string MissingClosingTag {
|
||||
get {
|
||||
return ResourceManager.GetString("MissingClosingTag", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Encountered an unknown tag. It was either not registered or exists in a different context..
|
||||
/// </summary>
|
||||
internal static string UnknownTag {
|
||||
get {
|
||||
return ResourceManager.GetString("UnknownTag", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The wrong number of arguments were passed to an {0} tag..
|
||||
/// </summary>
|
||||
internal static string WrongNumberOfArguments {
|
||||
get {
|
||||
return ResourceManager.GetString("WrongNumberOfArguments", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,237 +1,237 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
|
||||
namespace mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides methods for creating instances of PropertyDictionary.
|
||||
/// </summary>
|
||||
internal sealed class PropertyDictionary : IDictionary<string, object>
|
||||
{
|
||||
private static readonly Dictionary<Type, Dictionary<string, PropertyInfo>> _cache = new Dictionary<Type, Dictionary<string, PropertyInfo>>();
|
||||
|
||||
private readonly object _instance;
|
||||
private readonly Dictionary<string, PropertyInfo> _typeCache;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a PropertyDictionary.
|
||||
/// </summary>
|
||||
/// <param name="instance">The instance to wrap in the PropertyDictionary.</param>
|
||||
public PropertyDictionary(object instance)
|
||||
{
|
||||
_instance = instance;
|
||||
if (instance == null)
|
||||
{
|
||||
_typeCache = new Dictionary<string, PropertyInfo>();
|
||||
}
|
||||
else
|
||||
{
|
||||
_typeCache = getCacheType(_instance);
|
||||
}
|
||||
}
|
||||
|
||||
private static Dictionary<string, PropertyInfo> getCacheType(object instance)
|
||||
{
|
||||
Type type = instance.GetType();
|
||||
Dictionary<string, PropertyInfo> typeCache;
|
||||
if (!_cache.TryGetValue(type, out typeCache))
|
||||
{
|
||||
typeCache = new Dictionary<string, PropertyInfo>();
|
||||
BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy;
|
||||
foreach (PropertyInfo propertyInfo in type.GetProperties(flags))
|
||||
{
|
||||
if (!propertyInfo.IsSpecialName)
|
||||
{
|
||||
typeCache.Add(propertyInfo.Name, propertyInfo);
|
||||
}
|
||||
}
|
||||
_cache.Add(type, typeCache);
|
||||
}
|
||||
return typeCache;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying instance.
|
||||
/// </summary>
|
||||
public object Instance
|
||||
{
|
||||
get { return _instance; }
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IDictionary<string, object>.Add(string key, object value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a property with the given name exists.
|
||||
/// </summary>
|
||||
/// <param name="key">The name of the property.</param>
|
||||
/// <returns>True if the property exists; otherwise, false.</returns>
|
||||
public bool ContainsKey(string key)
|
||||
{
|
||||
return _typeCache.ContainsKey(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the properties in the type.
|
||||
/// </summary>
|
||||
public ICollection<string> Keys
|
||||
{
|
||||
get { return _typeCache.Keys; }
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
bool IDictionary<string, object>.Remove(string key)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get the value for the given property name.
|
||||
/// </summary>
|
||||
/// <param name="key">The name of the property to get the value for.</param>
|
||||
/// <param name="value">The variable to store the value of the property or the default value if the property is not found.</param>
|
||||
/// <returns>True if a property with the given name is found; otherwise, false.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">The name of the property was null.</exception>
|
||||
public bool TryGetValue(string key, out object value)
|
||||
{
|
||||
PropertyInfo propertyInfo;
|
||||
if (!_typeCache.TryGetValue(key, out propertyInfo))
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
value = getValue(propertyInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the values of all of the properties in the object.
|
||||
/// </summary>
|
||||
public ICollection<object> Values
|
||||
{
|
||||
get
|
||||
{
|
||||
ICollection<PropertyInfo> propertyInfos = _typeCache.Values;
|
||||
List<object> values = new List<object>();
|
||||
foreach (PropertyInfo propertyInfo in propertyInfos)
|
||||
{
|
||||
object value = getValue(propertyInfo);
|
||||
values.Add(value);
|
||||
}
|
||||
return values.AsReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value of the property with the given name.
|
||||
/// </summary>
|
||||
/// <param name="key">The name of the property to get or set.</param>
|
||||
/// <returns>The value of the property with the given name.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">The property name was null.</exception>
|
||||
/// <exception cref="System.Collections.Generic.KeyNotFoundException">The type does not have a property with the given name.</exception>
|
||||
/// <exception cref="System.ArgumentException">The property did not support getting or setting.</exception>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// The object does not match the target type, or a property is a value type but the value is null.
|
||||
/// </exception>
|
||||
public object this[string key]
|
||||
{
|
||||
get
|
||||
{
|
||||
PropertyInfo propertyInfo = _typeCache[key];
|
||||
return getValue(propertyInfo);
|
||||
}
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
set
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> item)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void ICollection<KeyValuePair<string, object>>.Clear()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> item)
|
||||
{
|
||||
PropertyInfo propertyInfo;
|
||||
if (!_typeCache.TryGetValue(item.Key, out propertyInfo))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
object value = getValue(propertyInfo);
|
||||
return Equals(item.Value, value);
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
|
||||
{
|
||||
List<KeyValuePair<string, object>> pairs = new List<KeyValuePair<string, object>>();
|
||||
ICollection<KeyValuePair<string, PropertyInfo>> collection = _typeCache;
|
||||
foreach (KeyValuePair<string, PropertyInfo> pair in collection)
|
||||
{
|
||||
PropertyInfo propertyInfo = pair.Value;
|
||||
object value = getValue(propertyInfo);
|
||||
pairs.Add(new KeyValuePair<string, object>(pair.Key, value));
|
||||
}
|
||||
pairs.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of properties in the type.
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get { return _typeCache.Count; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether updates will be ignored.
|
||||
/// </summary>
|
||||
bool ICollection<KeyValuePair<string, object>>.IsReadOnly
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> item)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the propety name/value pairs in the object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
|
||||
{
|
||||
foreach (KeyValuePair<string, PropertyInfo> pair in _typeCache)
|
||||
{
|
||||
object value = getValue(pair.Value);
|
||||
yield return new KeyValuePair<string, object>(pair.Key, value);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
private object getValue(PropertyInfo propertyInfo)
|
||||
{
|
||||
return propertyInfo.GetValue(_instance, null);
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides methods for creating instances of PropertyDictionary.
|
||||
/// </summary>
|
||||
internal sealed class PropertyDictionary : IDictionary<string, object>
|
||||
{
|
||||
private static readonly Dictionary<Type, Dictionary<string, PropertyInfo>> _cache = new Dictionary<Type, Dictionary<string, PropertyInfo>>();
|
||||
|
||||
private readonly object _instance;
|
||||
private readonly Dictionary<string, PropertyInfo> _typeCache;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a PropertyDictionary.
|
||||
/// </summary>
|
||||
/// <param name="instance">The instance to wrap in the PropertyDictionary.</param>
|
||||
public PropertyDictionary(object instance)
|
||||
{
|
||||
_instance = instance;
|
||||
if (instance == null)
|
||||
{
|
||||
_typeCache = new Dictionary<string, PropertyInfo>();
|
||||
}
|
||||
else
|
||||
{
|
||||
_typeCache = getCacheType(_instance);
|
||||
}
|
||||
}
|
||||
|
||||
private static Dictionary<string, PropertyInfo> getCacheType(object instance)
|
||||
{
|
||||
Type type = instance.GetType();
|
||||
Dictionary<string, PropertyInfo> typeCache;
|
||||
if (!_cache.TryGetValue(type, out typeCache))
|
||||
{
|
||||
typeCache = new Dictionary<string, PropertyInfo>();
|
||||
BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy;
|
||||
foreach (PropertyInfo propertyInfo in type.GetProperties(flags))
|
||||
{
|
||||
if (!propertyInfo.IsSpecialName)
|
||||
{
|
||||
typeCache.Add(propertyInfo.Name, propertyInfo);
|
||||
}
|
||||
}
|
||||
_cache.Add(type, typeCache);
|
||||
}
|
||||
return typeCache;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying instance.
|
||||
/// </summary>
|
||||
public object Instance
|
||||
{
|
||||
get { return _instance; }
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IDictionary<string, object>.Add(string key, object value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a property with the given name exists.
|
||||
/// </summary>
|
||||
/// <param name="key">The name of the property.</param>
|
||||
/// <returns>True if the property exists; otherwise, false.</returns>
|
||||
public bool ContainsKey(string key)
|
||||
{
|
||||
return _typeCache.ContainsKey(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the properties in the type.
|
||||
/// </summary>
|
||||
public ICollection<string> Keys
|
||||
{
|
||||
get { return _typeCache.Keys; }
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
bool IDictionary<string, object>.Remove(string key)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get the value for the given property name.
|
||||
/// </summary>
|
||||
/// <param name="key">The name of the property to get the value for.</param>
|
||||
/// <param name="value">The variable to store the value of the property or the default value if the property is not found.</param>
|
||||
/// <returns>True if a property with the given name is found; otherwise, false.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">The name of the property was null.</exception>
|
||||
public bool TryGetValue(string key, out object value)
|
||||
{
|
||||
PropertyInfo propertyInfo;
|
||||
if (!_typeCache.TryGetValue(key, out propertyInfo))
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
value = getValue(propertyInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the values of all of the properties in the object.
|
||||
/// </summary>
|
||||
public ICollection<object> Values
|
||||
{
|
||||
get
|
||||
{
|
||||
ICollection<PropertyInfo> propertyInfos = _typeCache.Values;
|
||||
List<object> values = new List<object>();
|
||||
foreach (PropertyInfo propertyInfo in propertyInfos)
|
||||
{
|
||||
object value = getValue(propertyInfo);
|
||||
values.Add(value);
|
||||
}
|
||||
return values.AsReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value of the property with the given name.
|
||||
/// </summary>
|
||||
/// <param name="key">The name of the property to get or set.</param>
|
||||
/// <returns>The value of the property with the given name.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">The property name was null.</exception>
|
||||
/// <exception cref="System.Collections.Generic.KeyNotFoundException">The type does not have a property with the given name.</exception>
|
||||
/// <exception cref="System.ArgumentException">The property did not support getting or setting.</exception>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// The object does not match the target type, or a property is a value type but the value is null.
|
||||
/// </exception>
|
||||
public object this[string key]
|
||||
{
|
||||
get
|
||||
{
|
||||
PropertyInfo propertyInfo = _typeCache[key];
|
||||
return getValue(propertyInfo);
|
||||
}
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
set
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> item)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void ICollection<KeyValuePair<string, object>>.Clear()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> item)
|
||||
{
|
||||
PropertyInfo propertyInfo;
|
||||
if (!_typeCache.TryGetValue(item.Key, out propertyInfo))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
object value = getValue(propertyInfo);
|
||||
return Equals(item.Value, value);
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
|
||||
{
|
||||
List<KeyValuePair<string, object>> pairs = new List<KeyValuePair<string, object>>();
|
||||
ICollection<KeyValuePair<string, PropertyInfo>> collection = _typeCache;
|
||||
foreach (KeyValuePair<string, PropertyInfo> pair in collection)
|
||||
{
|
||||
PropertyInfo propertyInfo = pair.Value;
|
||||
object value = getValue(propertyInfo);
|
||||
pairs.Add(new KeyValuePair<string, object>(pair.Key, value));
|
||||
}
|
||||
pairs.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of properties in the type.
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get { return _typeCache.Count; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether updates will be ignored.
|
||||
/// </summary>
|
||||
bool ICollection<KeyValuePair<string, object>>.IsReadOnly
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> item)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the propety name/value pairs in the object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
|
||||
{
|
||||
foreach (KeyValuePair<string, PropertyInfo> pair in _typeCache)
|
||||
{
|
||||
object value = getValue(pair.Value);
|
||||
yield return new KeyValuePair<string, object>(pair.Key, value);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
private object getValue(PropertyInfo propertyInfo)
|
||||
{
|
||||
return propertyInfo.GetValue(_instance, null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides utility methods that require regular expressions.
|
||||
|
|
|
@ -1,54 +1,54 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates a static block of text.
|
||||
/// </summary>
|
||||
internal sealed class StaticGenerator : IGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a StaticGenerator.
|
||||
/// </summary>
|
||||
public StaticGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the linked list node containing the current generator.
|
||||
/// </summary>
|
||||
public LinkedListNode<IGenerator> Node
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the static text.
|
||||
/// </summary>
|
||||
public string Value
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the static text from the final output.
|
||||
/// </summary>
|
||||
public void Prune()
|
||||
{
|
||||
if (Node != null)
|
||||
{
|
||||
Node.List.Remove(Node);
|
||||
Node = null;
|
||||
}
|
||||
}
|
||||
|
||||
void IGenerator.GetText(KeyScope scope, TextWriter writer)
|
||||
{
|
||||
writer.Write(Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates a static block of text.
|
||||
/// </summary>
|
||||
internal sealed class StaticGenerator : IGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a StaticGenerator.
|
||||
/// </summary>
|
||||
public StaticGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the linked list node containing the current generator.
|
||||
/// </summary>
|
||||
public LinkedListNode<IGenerator> Node
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the static text.
|
||||
/// </summary>
|
||||
public string Value
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the static text from the final output.
|
||||
/// </summary>
|
||||
public void Prune()
|
||||
{
|
||||
if (Node != null)
|
||||
{
|
||||
Node.List.Remove(Node);
|
||||
Node = null;
|
||||
}
|
||||
}
|
||||
|
||||
void IGenerator.GetText(KeyScope scope, TextWriter writer)
|
||||
{
|
||||
writer.Write(Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using mustache.Properties;
|
||||
using Mustache.Properties;
|
||||
using System.IO;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the attributes of a custom tag.
|
||||
|
|
|
@ -1,54 +1,54 @@
|
|||
using System;
|
||||
using mustache.Properties;
|
||||
|
||||
namespace mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a parameter belonging to a custom tag.
|
||||
/// </summary>
|
||||
public sealed class TagParameter
|
||||
{
|
||||
private readonly string _name;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a TagParameter.
|
||||
/// </summary>
|
||||
/// <param name="parameterName">The name of the parameter.</param>
|
||||
/// <exception cref="System.ArgumentException">The parameter name is null or an invalid identifier.</exception>
|
||||
public TagParameter(string parameterName)
|
||||
{
|
||||
if (!RegexHelper.IsValidIdentifier(parameterName))
|
||||
{
|
||||
throw new ArgumentException(Resources.BlankParameterName, "parameterName");
|
||||
}
|
||||
_name = parameterName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the parameter.
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the field is required.
|
||||
/// </summary>
|
||||
public bool IsRequired
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the default value to use when an argument is not provided
|
||||
/// for the parameter.
|
||||
/// </summary>
|
||||
public object DefaultValue
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Mustache.Properties;
|
||||
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a parameter belonging to a custom tag.
|
||||
/// </summary>
|
||||
public sealed class TagParameter
|
||||
{
|
||||
private readonly string _name;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a TagParameter.
|
||||
/// </summary>
|
||||
/// <param name="parameterName">The name of the parameter.</param>
|
||||
/// <exception cref="System.ArgumentException">The parameter name is null or an invalid identifier.</exception>
|
||||
public TagParameter(string parameterName)
|
||||
{
|
||||
if (!RegexHelper.IsValidIdentifier(parameterName))
|
||||
{
|
||||
throw new ArgumentException(Resources.BlankParameterName, "parameterName");
|
||||
}
|
||||
_name = parameterName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the parameter.
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the field is required.
|
||||
/// </summary>
|
||||
public bool IsRequired
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the default value to use when an argument is not provided
|
||||
/// for the parameter.
|
||||
/// </summary>
|
||||
public object DefaultValue
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,147 +1,147 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Removes unnecessary lines from the final output.
|
||||
/// </summary>
|
||||
internal sealed class Trimmer
|
||||
{
|
||||
private readonly LinkedList<LineDetails> _lines;
|
||||
private LinkedListNode<LineDetails> _currentLine;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a Trimmer.
|
||||
/// </summary>
|
||||
public Trimmer()
|
||||
{
|
||||
_lines = new LinkedList<LineDetails>();
|
||||
_currentLine = _lines.AddLast(new LineDetails());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the state of the trimmer, indicating that the given text was encountered before an inline tag.
|
||||
/// </summary>
|
||||
/// <param name="value">The text at the end of the format string.</param>
|
||||
/// <param name="generator">The generator created for the inline tag.</param>
|
||||
/// <returns>A static generator containing the passed text.</returns>
|
||||
public IEnumerable<StaticGenerator> RecordText(string value, bool isTag, bool isOutput)
|
||||
{
|
||||
int newLineIndex = value.IndexOf(Environment.NewLine);
|
||||
if (newLineIndex == -1)
|
||||
{
|
||||
StaticGenerator generator = new StaticGenerator() { Value = value };
|
||||
_currentLine.Value.Generators.Add(generator);
|
||||
_currentLine.Value.HasTag |= isTag;
|
||||
_currentLine.Value.HasOutput |= !String.IsNullOrWhiteSpace(value);
|
||||
yield return generator;
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] lines = value.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
|
||||
|
||||
// get the trailing generator
|
||||
string trailing = lines[0];
|
||||
StaticGenerator trailingGenerator = new StaticGenerator() { Value = trailing };
|
||||
_currentLine.Value.Generators.Add(trailingGenerator);
|
||||
_currentLine.Value.HasOutput |= !String.IsNullOrWhiteSpace(trailing);
|
||||
yield return trailingGenerator;
|
||||
|
||||
// get the middle generators
|
||||
for (int lineIndex = 1; lineIndex < lines.Length - 1; ++lineIndex)
|
||||
{
|
||||
string middle = lines[lineIndex];
|
||||
StaticGenerator middleGenerator = new StaticGenerator() { Value = middle };
|
||||
LineDetails middleDetails = new LineDetails() { HasTag = false };
|
||||
_currentLine = _lines.AddLast(middleDetails);
|
||||
_currentLine.Value.Generators.Add(middleGenerator);
|
||||
_currentLine.Value.HasOutput = true;
|
||||
yield return middleGenerator;
|
||||
}
|
||||
|
||||
// get the leading generator
|
||||
string leading = lines[lines.Length - 1];
|
||||
StaticGenerator leadingGenerator = new StaticGenerator() { Value = leading };
|
||||
LineDetails details = new LineDetails() { HasTag = isTag };
|
||||
_currentLine = _lines.AddLast(details);
|
||||
_currentLine.Value.Generators.Add(leadingGenerator);
|
||||
_currentLine.Value.HasOutput = !String.IsNullOrWhiteSpace(leading);
|
||||
yield return leadingGenerator;
|
||||
}
|
||||
if (isOutput)
|
||||
{
|
||||
_currentLine.Value.HasOutput = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Trim()
|
||||
{
|
||||
removeBlankLines();
|
||||
separateLines();
|
||||
removeEmptyGenerators();
|
||||
}
|
||||
|
||||
private void removeBlankLines()
|
||||
{
|
||||
LinkedListNode<LineDetails> current = _lines.First;
|
||||
while (current != null)
|
||||
{
|
||||
LineDetails details = current.Value;
|
||||
LinkedListNode<LineDetails> temp = current;
|
||||
current = current.Next;
|
||||
if (details.HasTag && !details.HasOutput)
|
||||
{
|
||||
foreach (StaticGenerator generator in temp.Value.Generators)
|
||||
{
|
||||
generator.Prune();
|
||||
}
|
||||
temp.List.Remove(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void separateLines()
|
||||
{
|
||||
LinkedListNode<LineDetails> current = _lines.First;
|
||||
while (current != _lines.Last)
|
||||
{
|
||||
List<StaticGenerator> generators = current.Value.Generators;
|
||||
StaticGenerator lastGenerator = generators[generators.Count - 1];
|
||||
lastGenerator.Value += Environment.NewLine;
|
||||
current = current.Next;
|
||||
}
|
||||
}
|
||||
|
||||
private void removeEmptyGenerators()
|
||||
{
|
||||
LinkedListNode<LineDetails> current = _lines.First;
|
||||
while (current != null)
|
||||
{
|
||||
foreach (StaticGenerator generator in current.Value.Generators)
|
||||
{
|
||||
if (generator.Value.Length == 0)
|
||||
{
|
||||
generator.Prune();
|
||||
}
|
||||
}
|
||||
current = current.Next;
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class LineDetails
|
||||
{
|
||||
public LineDetails()
|
||||
{
|
||||
Generators = new List<StaticGenerator>();
|
||||
}
|
||||
|
||||
public bool HasTag { get; set; }
|
||||
|
||||
public List<StaticGenerator> Generators { get; set; }
|
||||
|
||||
public bool HasOutput { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Removes unnecessary lines from the final output.
|
||||
/// </summary>
|
||||
internal sealed class Trimmer
|
||||
{
|
||||
private readonly LinkedList<LineDetails> _lines;
|
||||
private LinkedListNode<LineDetails> _currentLine;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a Trimmer.
|
||||
/// </summary>
|
||||
public Trimmer()
|
||||
{
|
||||
_lines = new LinkedList<LineDetails>();
|
||||
_currentLine = _lines.AddLast(new LineDetails());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the state of the trimmer, indicating that the given text was encountered before an inline tag.
|
||||
/// </summary>
|
||||
/// <param name="value">The text at the end of the format string.</param>
|
||||
/// <param name="generator">The generator created for the inline tag.</param>
|
||||
/// <returns>A static generator containing the passed text.</returns>
|
||||
public IEnumerable<StaticGenerator> RecordText(string value, bool isTag, bool isOutput)
|
||||
{
|
||||
int newLineIndex = value.IndexOf(Environment.NewLine);
|
||||
if (newLineIndex == -1)
|
||||
{
|
||||
StaticGenerator generator = new StaticGenerator() { Value = value };
|
||||
_currentLine.Value.Generators.Add(generator);
|
||||
_currentLine.Value.HasTag |= isTag;
|
||||
_currentLine.Value.HasOutput |= !String.IsNullOrWhiteSpace(value);
|
||||
yield return generator;
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] lines = value.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
|
||||
|
||||
// get the trailing generator
|
||||
string trailing = lines[0];
|
||||
StaticGenerator trailingGenerator = new StaticGenerator() { Value = trailing };
|
||||
_currentLine.Value.Generators.Add(trailingGenerator);
|
||||
_currentLine.Value.HasOutput |= !String.IsNullOrWhiteSpace(trailing);
|
||||
yield return trailingGenerator;
|
||||
|
||||
// get the middle generators
|
||||
for (int lineIndex = 1; lineIndex < lines.Length - 1; ++lineIndex)
|
||||
{
|
||||
string middle = lines[lineIndex];
|
||||
StaticGenerator middleGenerator = new StaticGenerator() { Value = middle };
|
||||
LineDetails middleDetails = new LineDetails() { HasTag = false };
|
||||
_currentLine = _lines.AddLast(middleDetails);
|
||||
_currentLine.Value.Generators.Add(middleGenerator);
|
||||
_currentLine.Value.HasOutput = true;
|
||||
yield return middleGenerator;
|
||||
}
|
||||
|
||||
// get the leading generator
|
||||
string leading = lines[lines.Length - 1];
|
||||
StaticGenerator leadingGenerator = new StaticGenerator() { Value = leading };
|
||||
LineDetails details = new LineDetails() { HasTag = isTag };
|
||||
_currentLine = _lines.AddLast(details);
|
||||
_currentLine.Value.Generators.Add(leadingGenerator);
|
||||
_currentLine.Value.HasOutput = !String.IsNullOrWhiteSpace(leading);
|
||||
yield return leadingGenerator;
|
||||
}
|
||||
if (isOutput)
|
||||
{
|
||||
_currentLine.Value.HasOutput = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Trim()
|
||||
{
|
||||
removeBlankLines();
|
||||
separateLines();
|
||||
removeEmptyGenerators();
|
||||
}
|
||||
|
||||
private void removeBlankLines()
|
||||
{
|
||||
LinkedListNode<LineDetails> current = _lines.First;
|
||||
while (current != null)
|
||||
{
|
||||
LineDetails details = current.Value;
|
||||
LinkedListNode<LineDetails> temp = current;
|
||||
current = current.Next;
|
||||
if (details.HasTag && !details.HasOutput)
|
||||
{
|
||||
foreach (StaticGenerator generator in temp.Value.Generators)
|
||||
{
|
||||
generator.Prune();
|
||||
}
|
||||
temp.List.Remove(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void separateLines()
|
||||
{
|
||||
LinkedListNode<LineDetails> current = _lines.First;
|
||||
while (current != _lines.Last)
|
||||
{
|
||||
List<StaticGenerator> generators = current.Value.Generators;
|
||||
StaticGenerator lastGenerator = generators[generators.Count - 1];
|
||||
lastGenerator.Value += Environment.NewLine;
|
||||
current = current.Next;
|
||||
}
|
||||
}
|
||||
|
||||
private void removeEmptyGenerators()
|
||||
{
|
||||
LinkedListNode<LineDetails> current = _lines.First;
|
||||
while (current != null)
|
||||
{
|
||||
foreach (StaticGenerator generator in current.Value.Generators)
|
||||
{
|
||||
if (generator.Value.Length == 0)
|
||||
{
|
||||
generator.Prune();
|
||||
}
|
||||
}
|
||||
current = current.Next;
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class LineDetails
|
||||
{
|
||||
public LineDetails()
|
||||
{
|
||||
Generators = new List<StaticGenerator>();
|
||||
}
|
||||
|
||||
public bool HasTag { get; set; }
|
||||
|
||||
public List<StaticGenerator> Generators { get; set; }
|
||||
|
||||
public bool HasOutput { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace mustache
|
||||
namespace Mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a tag that changes the scope to the object passed as an argument.
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<ProjectGuid>{D71B378F-A4BA-4263-A4F0-07A49A0C528D}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>mustache</RootNamespace>
|
||||
<RootNamespace>Mustache</RootNamespace>
|
||||
<AssemblyName>mustache-sharp</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
<?xml version="1.0"?>
|
||||
<package >
|
||||
<metadata>
|
||||
<id>$id$</id>
|
||||
<version>$version$</version>
|
||||
<title>$title$</title>
|
||||
<authors>$author$</authors>
|
||||
<owners>$author$</owners>
|
||||
<projectUrl>http://github.com/jehugaleahsa/mustache-sharp</projectUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>$description$</description>
|
||||
<releaseNotes>Initial commit</releaseNotes>
|
||||
<copyright>Copyright 2013</copyright>
|
||||
<tags>
|
||||
mustache handlebars.js text generation building template
|
||||
</tags>
|
||||
</metadata>
|
||||
<?xml version="1.0"?>
|
||||
<package >
|
||||
<metadata>
|
||||
<id>$id$</id>
|
||||
<version>$version$</version>
|
||||
<title>$title$</title>
|
||||
<authors>$author$</authors>
|
||||
<owners>$author$</owners>
|
||||
<projectUrl>http://github.com/jehugaleahsa/mustache-sharp</projectUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>$description$</description>
|
||||
<copyright>Copyright 2013</copyright>
|
||||
<tags>
|
||||
mustache handlebars.js text generation building template
|
||||
</tags>
|
||||
</metadata>
|
||||
</package>
|
Loading…
Reference in New Issue