Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Vladekk committed Mar 21, 2016
1 parent add7c15 commit 2cec82f
Show file tree
Hide file tree
Showing 68 changed files with 6,651 additions and 0 deletions.
63 changes: 63 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto

###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp

###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary

###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary

###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain
56 changes: 56 additions & 0 deletions src/DynamicTemplate/ArgumentDescription.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;

namespace DynamicTemplate
{
public enum ArgumentType
{
TextString,
TextStringExtended,
HtmlString,
HtmlStringExtended,
Integer,
Double,
Boolean,
DateTime
}

public class ArgumentDescription
{
private ArgumentType _type;
private string _identifier;
private string _label;

public ArgumentDescription() { }

public ArgumentDescription(ArgumentType type, string identifier, string label)
{
_type = type;
_identifier = identifier;
_label = label;
}

[XmlAttribute]
public ArgumentType Type
{
get { return _type; }
set { _type = value; }
}

[XmlAttribute]
public string Label
{
get { return _label; }
set { _label = value; }
}

[XmlText]
public string Identifier
{
get { return _identifier; }
set { _identifier = value; }
}
}
}
175 changes: 175 additions & 0 deletions src/DynamicTemplate/Compiler/BodyParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace DynamicTemplate.Compiler
{
class BodyParser
{
public TemplateOperation Parse(string str, ArgumentDescription[] args)
{
LanguageProvider lp = new CSharpLanguageProvider();

lp.Start(args);

IndexToPosition lcf = new IndexToPosition(str);
int pos = 0;
int codeStart;
while (str.Length > pos && 0 <= (codeStart = str.IndexOf("<%", pos)))
{
if (pos < codeStart)
{
lp.Literal(str.Substring(pos, codeStart - pos), lcf.Find(pos));
}

pos = codeStart + 2;

bool isExprMode = false;
if (str.Length > pos && str[pos] == '=')
{
pos++;
isExprMode = true;
}

int endIndex = str.IndexOf("%>", pos);
if (endIndex == -1)
{
throw new TemplateCompilationException(
"Couldn't find a matching \"%>\"",
lcf.Find(pos)
);
}

Position sourcePos = lcf.Find(pos);
string code = str.Substring(pos, endIndex - pos);
if (isExprMode)
lp.Expression(code, sourcePos);
else
lp.Code(code, sourcePos);

pos = endIndex + 2;

// skip trailing CRLF? Only if the current code block is
// not in expression mode, and if there's no significant text
// on the same line as the <% or the %>.
if (!isExprMode
&& IsLinePrefixOnlyWhitespace(str, codeStart)
&& IsLineSuffixOnlyWhitespace(str, pos))
{
while (pos < str.Length && str[pos] != '\n')
pos++;
if (pos < str.Length)
pos++;
}
}

if (pos < str.Length)
{
lp.Literal(str.Substring(pos), lcf.Find(pos));
}

return lp.End();
}

private static bool IsLinePrefixOnlyWhitespace(string str, int index)
{
for (int i = index - 1; i >= 0; i--)
{
if (!char.IsWhiteSpace(str[i]))
return false;
else if (str[i] == '\n')
return true;
}
return true;
}

private static bool IsLineSuffixOnlyWhitespace(string str, int index)
{
for (int i = index; i < str.Length; i++)
{
if (!char.IsWhiteSpace(str[i]))
return false;
else if (str[i] == '\n')
return true;
}
return true;
}
}

/// <summary>
/// Given an index into a string, returns a line/column position.
/// This implementation is a stateful class that optimizes performance
/// for multiple queries whose index values are further and further along
/// in the string.
/// </summary>
class IndexToPosition
{
private readonly string _str;
private int _pos;
private int _line;
private int _col;

public IndexToPosition(string str)
{
_str = str;
_pos = 0;
_line = 1;
_col = 1;
}

public Position Find(int index)
{
if (_pos > index)
{
// we've gone backwards; start over

_pos = 0;
_line = 1;
_col = 1;
}

for (; _pos < index; _pos++)
{
switch (_str[_pos])
{
case '\n':
_line++;
_col = 1;
break;
default:
_col++;
break;
}
}

return new Position(_line, _col);
}

public static int ReverseFind(string str, int line, int column)
{
int pos = -1;
for (int i = 1; i < line; i++)
{
pos = str.IndexOf('\n', pos + 1);
if (pos == -1)
return -1;
}
pos++;

for (int i = 1; i < column; i++)
{
pos++;
if (pos >= str.Length)
return -1;
if ('\n' == str[pos])
return -1;
}

if (pos >= str.Length)
return -1;

return pos;
}
}
}
Loading

0 comments on commit 2cec82f

Please sign in to comment.