feat: expand cockpit integrations and support workflows

Add Phoenix remote desktop, action connector, documentation engine, and gamification support. Refactor support-case processing and search/action UI, and update installer assets and dependencies.
This commit is contained in:
Meik
2026-07-13 11:16:53 +02:00
parent bbedbf71c8
commit 0b52999b1d
303 changed files with 11235 additions and 3580 deletions

View File

@@ -0,0 +1,41 @@
using F4SD.DocuEngine.DocuEngineDataProvider;
using F4SD.DocuEngine.DocuEngineParser;
using F4SD.DocuEngine.DocuEngineParser.ContentBlock;
using F4SD.DocuEngine.DocuEngineParser.Exceptions;
using System;
using System.Collections.Generic;
using System.Text;
namespace F4SD.DocuEngine
{
public class DocuEngine
{
public string DocuTemplate { get; private set; }
public IDocuEngineDataContainer Container { get; private set; }
private ParsingContext parsingContext;
public DocuEngine(string docuTemplate, IDocuEngineDataContainer container)
{
DocuTemplate = docuTemplate;
Container = container;
}
public string ParseTemplate()
{
var index = 0;
parsingContext = new ParsingContext();
ContentBlock contentBlock = new ContentBlock(DocuTemplate, Container);
try
{
parsingContext.Append(contentBlock.ParseContentBlock(ref index));
}
catch (DocuEngineParser.Exceptions.DocuEngineParserException parserException)
{
parsingContext.Append(parserException.CurrentText);
parsingContext.Append(parserException.PrintedErrorMessage);
return parsingContext.GetFinalText();
}
return parsingContext.GetFinalText();
}
}
}

View File

@@ -0,0 +1,93 @@
using C4IT.F4SD.DisplayFormatting;
using System.Collections.Generic;
using System.Linq;
namespace F4SD.DocuEngine.DocuEngineDataProvider
{
public class DocuEngineDataProperty : IDocuEngineDataProperty
{
public object Value { get; set; }
public RawValueType? ValueType { get; set; }
}
public class DocuEngineDataContainer : Dictionary<string, IDocuEngineDataToken>, IDocuEngineDataContainer
{
public IDocuEngineDataToken GetByName(string tokenName)
{
var tokenTree = tokenName.Split('.');
if (this.TryGetValue(tokenTree[0], out IDocuEngineDataToken token))
{
if (tokenTree.Length > 1)
{
switch (token)
{
case IDocuEngineDataContainer container:
return container.GetByName(string.Join(".", tokenTree.Skip(1)));
case IDocuEngineDataProperty property:
return property;
case IDocuEngineDataEnumeration enumeration:
return new DocuEngineDataProperty() { Value = tokenTree[0] };
default:
//Syntax Error
break;
}
}
else
{
switch (token)
{
case IDocuEngineDataContainer container:
return container;
case IDocuEngineDataProperty property:
return property;
case IDocuEngineDataEnumeration enumeration:
return enumeration;
default:
//Syntax Error
break;
}
}
return null;
}
else
{
//Syntax Error
return null;
}
}
public IDocuEngineDataContainer GetContainerByName(string containerName)
{
var token = GetByName(containerName);
if (token is IDocuEngineDataContainer container)
{
return container;
}
return null;
}
public IDocuEngineDataProperty GetPropertyByName(string propertyName)
{
var token = GetByName(propertyName);
if (token is IDocuEngineDataProperty property)
{
return property;
}
return null;
}
public IDocuEngineDataEnumeration GetEnumerationByName(string enumName)
{
var token = GetByName(enumName);
if (token is IDocuEngineDataEnumeration enumeration)
{
return enumeration;
}
return null;
}
}
public class DocuEngineDataEnumeration : List<IDocuEngineDataToken>, IDocuEngineDataEnumeration
{
}
}

View File

@@ -0,0 +1,31 @@
using C4IT.F4SD.DisplayFormatting;
using System.Collections.Generic;
namespace F4SD.DocuEngine.DocuEngineDataProvider
{
public interface IDocuEngineDataToken
{
}
public interface IDocuEngineDataIllegal : IDocuEngineDataToken
{
}
public interface IDocuEngineDataProperty : IDocuEngineDataToken
{
object Value { get; set; }
RawValueType? ValueType { get; set; }
}
public interface IDocuEngineDataContainer : IDocuEngineDataToken
{
IDocuEngineDataToken GetByName(string name);
IDocuEngineDataContainer GetContainerByName(string containerName);
IDocuEngineDataEnumeration GetEnumerationByName(string enumName);
IDocuEngineDataProperty GetPropertyByName(string propertyName);
}
public interface IDocuEngineDataEnumeration : IEnumerable<IDocuEngineDataToken>, IDocuEngineDataToken
{
}
}

View File

@@ -0,0 +1,227 @@
using C4IT.F4SD.DisplayFormatting;
using F4SD.DocuEngine.DocuEngineDataProvider;
using F4SD.DocuEngine.DocuEngineParser.Exceptions;
using System;
using System.Linq;
using System.Text.RegularExpressions;
namespace F4SD.DocuEngine.DocuEngineParser.ContentBlock
{
internal partial class ContentBlock
{
public string DocuTemplate { get; private set; }
public IDocuEngineDataContainer Container { get; private set; }
private ParsingContext parsingContext;
public ContentBlock(string DocuTemplate, IDocuEngineDataContainer Container)
{
this.DocuTemplate = DocuTemplate;
this.Container = Container;
parsingContext = new ParsingContext();
}
public string ParseContentBlock(ref int index)
{
bool isContentBlockFinished = false;
try
{
while (!isContentBlockFinished)
{
ParseTextBlock(ref index, out var finished);
if (finished)
{
isContentBlockFinished = true;
}
else
{
ParseCommandBlock(ref index);
}
}
}
catch (DocuEngineParserException parserException)
{
parsingContext.Append(parserException.CurrentText);
parserException.AddToCurrentText(parsingContext.GetFinalText());
throw;
}
return parsingContext.GetFinalText();
}
private void ParseTextBlock(ref int index, out bool isContextBlockFinished)
{
bool foundTrigger = false;
string[] keywords = { "@@", "[[", "]]", "{{", "}}" };
string pattern = string.Join("|", keywords.Select(Regex.Escape));
Regex regex = new Regex(pattern);
isContextBlockFinished = false;
while (!foundTrigger)
{
Match match = regex.Match(DocuTemplate, index);
if (match.Success)
{
parsingContext.Append(DocuTemplate.Substring(index, match.Index - index));
index = match.Index;
switch (match.Value)
{
case "@@":
if (DocuTemplate.Substring(index, 3).Equals("@@@"))
{
parsingContext.Append("@@");
index += 3;
}
else
{
foundTrigger = true;
index += 2;
}
break;
case "[[":
if (DocuTemplate.Substring(index, 3).Equals("[[["))
{
parsingContext.Append("[[");
index += 3;
}
else
{
index += 2;
SkipWhiteSpace(ref index);
string variableName = ParseVariableName(ref index);
SkipWhiteSpace(ref index);
if (DocuTemplate.ElementAtOrDefault(index).Equals(';'))
{
index++;
SkipWhiteSpace(ref index);
string displayTypeString = ParseDisplayType(ref index);
RawValueType? displayType = null;
if (Enum.TryParse(displayTypeString, true, out RawValueType parseDisplayType))
{
displayType = parseDisplayType;
}
parsingContext.Append(SubstituteVariable(variableName, displayType));
SkipWhiteSpace(ref index);
if (DocuTemplate.Substring(index, 2).Equals("]]") && !(DocuTemplate.Substring(index, 3).Equals("]]]")))
{
index += 2;
continue;
}
else
{
throw new SyntaxErrorException("]]", DocuTemplate.Substring(index, 3));
}
}
else if (DocuTemplate.Substring(index, 2).Equals("]]"))
{
parsingContext.Append(SubstituteVariable(variableName, null));
index += 2;
continue;
}
else
{
throw new SyntaxErrorException("]]\" / \";", DocuTemplate.Substring(index, 3));
}
}
break;
case "]]":
if (DocuTemplate.Substring(index, 3).Equals("]]]"))
{
parsingContext.Append("]]");
index += 3;
}
else
{
throw new SyntaxErrorException("]]]", "]]");
}
break;
case "{{":
if (DocuTemplate.Substring(index, 3).Equals("{{{"))
{
parsingContext.Append("{{");
index += 3;
}
else
{
throw new SyntaxErrorException("{{{", "{{");
}
break;
case "}}":
if (DocuTemplate.Substring(index, 3).Equals("}}}"))
{
parsingContext.Append("}}");
index += 3;
}
else if (DocuTemplate.Substring(index, 3).Equals("}};"))
{
foundTrigger = true;
isContextBlockFinished = true;
index += 3;
}
else
{
foundTrigger = true;
isContextBlockFinished = true;
index += 2;
}
break;
}
}
else
{
int length = DocuTemplate.Length - index;
if (length < 0)
{
length = 0;
}
else if (length > 15)
{
length = 15;
}
throw new SyntaxErrorException("}};", DocuTemplate.Substring(index, length));
}
}
}
private void ParseCommandBlock(ref int index)
{
string[] keywords = { "(" };
string pattern = string.Join("|", keywords.Select(Regex.Escape));
Regex regex = new Regex(pattern);
Match match = regex.Match(DocuTemplate, index);
if (match.Success)
{
string commandName = "";
commandName = DocuTemplate.Substring(index, match.Index - index);
index = match.Index + 1;
switch (commandName)
{
case "if":
ParseIfCommand(ref index);
break;
case "switch":
ParseSwitchCommand(ref index);
break;
case "foreach":
ParseForeachCommand(ref index);
break;
case "include":
//TODO
break;
}
}
else
{
int length = DocuTemplate.Length - index;
if (length < 0)
{
length = 0;
}
else if (length > 15)
{
length = 15;
}
throw new SyntaxErrorException("if\" / \"switch\" / \"foreach", DocuTemplate.Substring(index, length));
}
}
}
}

View File

@@ -0,0 +1,52 @@
using F4SD.DocuEngine.DocuEngineDataProvider;
using F4SD.DocuEngine.DocuEngineParser.Exceptions;
using System.ComponentModel;
using System.Linq;
namespace F4SD.DocuEngine.DocuEngineParser.ContentBlock
{
internal partial class ContentBlock
{
private void ParseForeachCommand(ref int index)
{
string variableName = "";
string enumName = "";
int tempIndex = 0;
SkipWhiteSpace(ref index);
variableName += ParseVariableName(ref index);
SkipWhiteSpace(ref index);
if (!(DocuTemplate.ElementAtOrDefault(index).Equals(';')))
{
throw new SyntaxErrorException(";", DocuTemplate.ElementAtOrDefault(index).ToString());
}
index++;
SkipWhiteSpace(ref index);
enumName += ParseVariableName(ref index);
SkipWhiteSpace(ref index);
if (!(DocuTemplate.ElementAtOrDefault(index).Equals(')')))
{
throw new SyntaxErrorException(")", DocuTemplate.ElementAtOrDefault(index).ToString());
}
index++;
SkipWhiteSpace(ref index);
if (!DocuTemplate.Substring(index, 2).Equals("{{"))
{
throw new SyntaxErrorException("{{", DocuTemplate.Substring(index, 2));
}
index += 2;
IDocuEngineDataEnumeration enumeration = Container.GetEnumerationByName(enumName);
if (enumeration == null)
{
//Syntax Error
}
tempIndex = index;
foreach (var token in enumeration)
{
index = tempIndex;
ContentBlock foreachBlock = new ContentBlock(DocuTemplate, new DocuEngineDataContainer() { { variableName, token } });
parsingContext.Append(foreachBlock.ParseContentBlock(ref index));
}
}
}
}

View File

@@ -0,0 +1,291 @@
using C4IT.F4SD.DisplayFormatting;
using F4SD.DocuEngine.DocuEngineParser.Exceptions;
using System.ComponentModel;
using System.Linq;
using System.Text.RegularExpressions;
namespace F4SD.DocuEngine.DocuEngineParser.ContentBlock
{
internal partial class ContentBlock
{
private string ParseVariableType(ref int index)
{
bool foundTypeEnd = false;
string variableType = "";
while (!foundTypeEnd)
{
char c = DocuTemplate.ElementAt(index);
if (char.IsLetter(c))
{
variableType += c;
index++;
}
else
{
foundTypeEnd = true;
}
}
return variableType;
}
private string ParseVariableName(ref int index)
{
bool foundVariableEnd = false;
string variableName = "";
while (!foundVariableEnd)
{
char c = DocuTemplate.ElementAt(index);
if (char.IsLetterOrDigit(c) || c == '.')
{
variableName += c;
index++;
}
else
{
foundVariableEnd = true;
}
}
return variableName;
}
private void SkipWhiteSpace(ref int index)
{
bool foundNonWhiteSpace = false;
while (!foundNonWhiteSpace)
{
char c = DocuTemplate.ElementAt(index);
if (char.IsWhiteSpace(c))
{
index++;
}
else
{
foundNonWhiteSpace = true;
}
}
}
private string ParseDisplayType(ref int index)
{
bool foundDisplayTypeEnd = false;
string displayType = "";
while (!foundDisplayTypeEnd)
{
char c = DocuTemplate.ElementAt(index);
if (char.IsLetterOrDigit(c))
{
displayType += c;
index++;
}
else
{
foundDisplayTypeEnd = true;
}
}
return displayType;
}
private string SubstituteVariable(string variableName, RawValueType? displayType)
{
IRawValueFormatter rawValueFormatter = new RawValueFormatter();
var property = Container.GetPropertyByName(variableName);
if (property == null)
{
//Syntax Error
}
if (displayType != null)
{
return rawValueFormatter.GetDisplayValue(property.Value, (RawValueType)displayType, null);
}
else if (property.ValueType != null)
{
return rawValueFormatter.GetDisplayValue(property.Value, (RawValueType)property.ValueType, null);
}
else
{
return property.Value.ToString();
}
}
private char ParseComparator(ref int index)
{
char comparator = DocuTemplate.ElementAtOrDefault(index);
if (!(comparator == '<' || comparator == '>' || comparator == '=' || comparator == '!'))
{
throw new SyntaxErrorException("<\" / \">\" / \"=\" / \"!", comparator.ToString());
}
index++;
return comparator;
}
private string ParseValue(ref int index)
{
string value = "";
string pattern = @"("")(.*?)(""\s*\))";
Regex regex = new Regex(pattern);
Match match = regex.Match(DocuTemplate, index);
if (match.Success)
{
value = match.Groups[2].Value;
string wholeMatch = match.Value.ToString();
index += wholeMatch.Length;
}
else
{
throw new SyntaxErrorException("\"VariableName\")", "");
}
return value;
}
private bool CheckCondition(string variableType, string variableName, char comparator, string value)
{
string stringVariable = "";
var property = Container.GetPropertyByName(variableName);
if (property == null)
{
//Syntax Error
}
stringVariable = property.Value.ToString();
switch (variableType)
{
case "string":
if (!(comparator == '=' || comparator == '!'))
{
throw new SyntaxErrorException("=\" / \"!", comparator.ToString());
}
return CompareStrings(stringVariable, comparator, value);
case "int":
if (!(comparator == '<' || comparator == '>' || comparator == '=' || comparator == '!'))
{
throw new SyntaxErrorException("<\" / \">\" / \"=\" / \"!", comparator.ToString());
}
if (!(int.TryParse(value, out var intValue)))
{
throw new VariableErrorException(value, "int");
}
stringVariable = stringVariable.Replace("\"", "");
if (!(int.TryParse(stringVariable, out var intVariable)))
{
throw new VariableErrorException(stringVariable, "int");
}
return CompareIntegers(intVariable, comparator, intValue);
case "bool":
if (!(comparator == '=' || comparator == '!'))
{
throw new SyntaxErrorException("=\" / \"!", comparator.ToString());
}
if (!(bool.TryParse(value, out var boolValue)))
{
throw new VariableErrorException(value, "bool");
}
if (!(bool.TryParse(stringVariable, out var boolVariable)))
{
throw new VariableErrorException(stringVariable, "bool");
}
return CompareBooleans(boolVariable, comparator, boolValue);
default:
throw new SyntaxErrorException("string\" / \"int\" / \"bool", variableType);
}
}
private bool CompareStrings(string variable, char comparator, string value)
{
switch (comparator)
{
case '=':
if (variable == value)
{
return true;
}
else
{
return false;
}
case '!':
if (variable != value)
{
return true;
}
else
{
return false;
}
default:
return false;
}
}
private bool CompareIntegers(int variable, char comparator, int value)
{
switch (comparator)
{
case '=':
if (variable == value)
{
return true;
}
else
{
return false;
}
case '!':
if (variable != value)
{
return true;
}
else
{
return false;
}
case '>':
if (variable > value)
{
return true;
}
else
{
return false;
}
case '<':
if (variable < value)
{
return true;
}
else
{
return false;
}
default:
return false;
}
}
private bool CompareBooleans(bool variable, char comparator, bool value)
{
switch (comparator)
{
case '=':
if (variable == value)
{
return true;
}
else
{
return false;
}
case '!':
if (variable != value)
{
return true;
}
else
{
return false;
}
default:
return false;
}
}
}
}

View File

@@ -0,0 +1,175 @@
using F4SD.DocuEngine.DocuEngineParser.Exceptions;
using System.ComponentModel;
using System.Linq;
namespace F4SD.DocuEngine.DocuEngineParser.ContentBlock
{
internal partial class ContentBlock
{
private void ParseIfCommand(ref int index)
{
string tempString = "";
bool foundTrueCondition = false;
bool foundAllElseIf = false;
int tempIndex = 0;
tempString = ParseIfBlock(ref index, out var isIfConditionTrue);
if (isIfConditionTrue)
{
foundTrueCondition = true;
parsingContext.Append(tempString);
}
tempString = "";
while (!foundAllElseIf)
{
tempIndex = index;
SkipWhiteSpace(ref index);
if (DocuTemplate.Substring(index, 7).Equals("else-if"))
{
index += 7;
tempString += ParseElseIfBlock(ref index, out var isElseIfConditionTrue);
if (isElseIfConditionTrue && !foundTrueCondition)
{
foundTrueCondition = true;
parsingContext.Append(tempString);
}
tempString = "";
}
else
{
foundAllElseIf = true;
index = tempIndex;
}
}
tempIndex = index;
SkipWhiteSpace(ref index);
if (DocuTemplate.Substring(index, 4).Equals("else"))
{
index += 4;
tempString += ParseElseBlock(ref index);
if (!foundTrueCondition)
{
foundTrueCondition = true;
parsingContext.Append(tempString);
tempString = "";
}
}
else
{
index = tempIndex;
}
}
private string ParseIfBlock(ref int index, out bool isConditionTrue)
{
string returnString = "";
string variableType = "";
string variableName = "";
char comparator;
string value = "";
SkipWhiteSpace(ref index);
variableType += ParseVariableType(ref index);
SkipWhiteSpace(ref index);
if (!(DocuTemplate.ElementAtOrDefault(index).Equals(';')))
{
throw new SyntaxErrorException(";", DocuTemplate.ElementAtOrDefault(index).ToString());
}
index++;
SkipWhiteSpace(ref index);
variableName += ParseVariableName(ref index);
SkipWhiteSpace(ref index);
if (!(DocuTemplate.ElementAtOrDefault(index).Equals(';')))
{
throw new SyntaxErrorException(";", DocuTemplate.ElementAtOrDefault(index).ToString());
}
index++;
SkipWhiteSpace(ref index);
comparator = ParseComparator(ref index);
SkipWhiteSpace(ref index);
if (!(DocuTemplate.ElementAtOrDefault(index).Equals(';')))
{
throw new SyntaxErrorException(";", DocuTemplate.ElementAtOrDefault(index).ToString());
}
index++;
SkipWhiteSpace(ref index);
value += ParseValue(ref index);
SkipWhiteSpace(ref index);
isConditionTrue = CheckCondition(variableType, variableName, comparator, value);
SkipWhiteSpace(ref index);
if (!DocuTemplate.Substring(index, 2).Equals("{{"))
{
throw new SyntaxErrorException("{{", DocuTemplate.Substring(index, 2));
}
index += 2;
ContentBlock contentBlock = new ContentBlock(DocuTemplate, Container);
returnString += contentBlock.ParseContentBlock(ref index);
return returnString;
}
private string ParseElseIfBlock(ref int index, out bool isConditionTrue)
{
string returnString = "";
string variableType = "";
string variableName = "";
char comparator;
string value = "";
SkipWhiteSpace(ref index);
if (!(DocuTemplate.ElementAt(index).Equals('(')))
{
throw new SyntaxErrorException("(", DocuTemplate.ElementAtOrDefault(index).ToString());
}
index++;
SkipWhiteSpace(ref index);
variableType += ParseVariableType(ref index);
SkipWhiteSpace(ref index);
if (!(DocuTemplate.ElementAtOrDefault(index).Equals(';')))
{
throw new SyntaxErrorException(";", DocuTemplate.ElementAtOrDefault(index).ToString());
}
index++;
SkipWhiteSpace(ref index);
variableName += ParseVariableName(ref index);
SkipWhiteSpace(ref index);
if (!(DocuTemplate.ElementAtOrDefault(index).Equals(';')))
{
throw new SyntaxErrorException(";", DocuTemplate.ElementAtOrDefault(index).ToString());
}
index++;
SkipWhiteSpace(ref index);
comparator = ParseComparator(ref index);
SkipWhiteSpace(ref index);
if (!(DocuTemplate.ElementAtOrDefault(index).Equals(';')))
{
throw new SyntaxErrorException(";", DocuTemplate.ElementAtOrDefault(index).ToString());
}
index++;
SkipWhiteSpace(ref index);
value += ParseValue(ref index);
SkipWhiteSpace(ref index);
isConditionTrue = CheckCondition(variableType, variableName, comparator, value);
SkipWhiteSpace(ref index);
if (!DocuTemplate.Substring(index, 2).Equals("{{"))
{
throw new SyntaxErrorException("{{", DocuTemplate.Substring(index, 2));
}
index += 2;
ContentBlock contentBlock = new ContentBlock(DocuTemplate, Container);
returnString += contentBlock.ParseContentBlock(ref index);
return returnString;
}
private string ParseElseBlock(ref int index)
{
string returnString = "";
SkipWhiteSpace(ref index);
if (!DocuTemplate.Substring(index, 2).Equals("{{"))
{
throw new SyntaxErrorException("{{", DocuTemplate.Substring(index, 2));
}
index += 2;
ContentBlock contentBlock = new ContentBlock(DocuTemplate, Container);
returnString += contentBlock.ParseContentBlock(ref index);
return returnString;
}
}
}

View File

@@ -0,0 +1,127 @@
using F4SD.DocuEngine.DocuEngineParser.Exceptions;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace F4SD.DocuEngine.DocuEngineParser.ContentBlock
{
internal partial class ContentBlock
{
private void ParseSwitchCommand(ref int index)
{
string tempString = "";
bool foundTrueCase = false;
bool foundAllCases = false;
int tempIndex = 0;
(string VariableType, string VariableName) switchVariable = ParseSwitchBlock(ref index);
while (!foundAllCases)
{
tempIndex = index;
SkipWhiteSpace(ref index);
if (DocuTemplate.Substring(index, 4).Equals("case"))
{
index += 4;
tempString += ParseCaseBlock(ref index, switchVariable, out var isCaseTrue);
if (isCaseTrue && !foundTrueCase)
{
foundTrueCase = true;
parsingContext.Append(tempString);
}
tempString = "";
}
else
{
foundAllCases = true;
index = tempIndex;
}
}
tempIndex = index;
SkipWhiteSpace(ref index);
if (DocuTemplate.Substring(index, 7).Equals("default"))
{
index += 7;
tempString += ParseDefaultBlock(ref index);
if (!foundTrueCase)
{
foundTrueCase = true;
parsingContext.Append(tempString);
tempString = "";
}
}
else
{
index = tempIndex;
}
}
private (string VariableType, string VariableName) ParseSwitchBlock(ref int index)
{
string variableName = "";
string variableType = "";
SkipWhiteSpace(ref index);
variableType = ParseVariableType(ref index);
SkipWhiteSpace(ref index);
if (!(DocuTemplate.ElementAtOrDefault(index).Equals(';')))
{
throw new SyntaxErrorException(";", DocuTemplate.ElementAtOrDefault(index).ToString());
}
index++;
SkipWhiteSpace(ref index);
variableName = ParseVariableName(ref index);
SkipWhiteSpace(ref index);
if (!(DocuTemplate.ElementAtOrDefault(index).Equals(')')))
{
throw new SyntaxErrorException(")", DocuTemplate.ElementAtOrDefault(index).ToString());
}
index++;
SkipWhiteSpace(ref index);
if (!DocuTemplate.Substring(index, 2).Equals("{{"))
{
throw new SyntaxErrorException("{{", DocuTemplate.Substring(index, 2));
}
index += 2;
return (variableType, variableName);
}
private string ParseCaseBlock(ref int index, (string VariableType, string VariableName) switchVariable, out bool isCaseTrue)
{
string returnString = "";
isCaseTrue = false;
string value = "";
SkipWhiteSpace(ref index);
if (!(DocuTemplate.ElementAtOrDefault(index).Equals('(')))
{
throw new SyntaxErrorException("(", DocuTemplate.ElementAtOrDefault(index).ToString());
}
index++;
SkipWhiteSpace(ref index);
value = ParseValue(ref index);
isCaseTrue = CheckCondition(switchVariable.VariableType, switchVariable.VariableName, '=', value);
SkipWhiteSpace(ref index);
if (!DocuTemplate.Substring(index, 2).Equals("{{"))
{
throw new SyntaxErrorException("{{", DocuTemplate.Substring(index, 2));
}
index += 2;
ContentBlock contentBlock = new ContentBlock(DocuTemplate, Container);
returnString += contentBlock.ParseContentBlock(ref index);
return returnString;
}
private string ParseDefaultBlock(ref int index)
{
string returnString = "";
SkipWhiteSpace(ref index);
if (!DocuTemplate.Substring(index, 2).Equals("{{"))
{
throw new SyntaxErrorException("{{", DocuTemplate.Substring(index, 2));
}
index += 2;
ContentBlock contentBlock = new ContentBlock(DocuTemplate, Container);
returnString += contentBlock.ParseContentBlock(ref index);
return returnString;
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
namespace F4SD.DocuEngine.DocuEngineParser
{
internal abstract class DocuEngineParserException : Exception
{
public string CurrentText { get; protected set; }
public string PrintedErrorMessage { get; protected set; }
public DocuEngineParserException(string message) : base(message)
{
}
public abstract void AddToCurrentText(string text);
}
}

View File

@@ -0,0 +1,15 @@
using System;
namespace F4SD.DocuEngine.DocuEngineParser.Exceptions
{
internal abstract class DocuEngineParserException : Exception
{
public string CurrentText { get; protected set; }
public string PrintedErrorMessage { get; protected set; }
public DocuEngineParserException(string message) : base(message)
{
}
public abstract void AddToCurrentText(string text);
}
}

View File

@@ -0,0 +1,26 @@
namespace F4SD.DocuEngine.DocuEngineParser.Exceptions
{
internal class SyntaxErrorException : DocuEngineParserException
{
private const string errorMessageTemplate = "<<Syntax Error | Expected Characters: \"{0}\" | Actual Characters: \"{1}\">>";
private const string defaultMessage = "You're syntax is wrong. Get good.";
public SyntaxErrorException(string currentText) : base(defaultMessage)
{
CurrentText = currentText;
}
public SyntaxErrorException(string expected, string actual) : base(defaultMessage)
{
PrintedErrorMessage = string.Format(errorMessageTemplate, expected, actual);
}
public SyntaxErrorException(string currentText, string expected, string actual) : base(defaultMessage)
{
CurrentText = currentText;
PrintedErrorMessage = string.Format(errorMessageTemplate, expected, actual);
}
public override void AddToCurrentText(string text)
{
CurrentText = text + CurrentText;
}
}
}

View File

@@ -0,0 +1,25 @@
namespace F4SD.DocuEngine.DocuEngineParser.Exceptions
{
internal class VariableErrorException : DocuEngineParserException
{
private const string errorMessageTemplate = "<<Variable Error | \"{0}\" can't be converted to type \"{1}\">>";
private const string defaultMessage = "Your variable is the wrong type. Get good.";
public VariableErrorException(string currentText) : base(defaultMessage)
{
CurrentText = currentText;
}
public VariableErrorException(string expected, string actual) : base(defaultMessage)
{
PrintedErrorMessage = string.Format(errorMessageTemplate, expected, actual);
}
public VariableErrorException(string currentText, string expected, string actual) : base(defaultMessage)
{
CurrentText = currentText;
PrintedErrorMessage = string.Format(errorMessageTemplate, expected, actual);
}
public override void AddToCurrentText(string text)
{
CurrentText = text + CurrentText;
}
}
}

View File

@@ -0,0 +1,13 @@
using System.Text;
namespace F4SD.DocuEngine.DocuEngineParser
{
internal class ParsingContext
{
private readonly StringBuilder _stringBuilder = new StringBuilder();
public void Append(string text) => _stringBuilder.Append(text);
public string GetFinalText() => _stringBuilder.ToString();
}
}

View File

@@ -0,0 +1,26 @@
namespace F4SD.DocuEngine.DocuEngineParser
{
internal class SyntaxErrorException : DocuEngineParserException
{
private const string errorMessageTemplate = "<<Syntax Error | Expected Characters: \"{0}\" | Actual Characters: \"{1}\">>";
private const string defaultMessage = "You're syntax is wrong. Get good.";
public SyntaxErrorException(string currentText) : base(defaultMessage)
{
CurrentText = currentText;
}
public SyntaxErrorException(string expected, string actual) : base(defaultMessage)
{
PrintedErrorMessage = string.Format(errorMessageTemplate, expected, actual);
}
public SyntaxErrorException(string currentText, string expected, string actual) : base(defaultMessage)
{
CurrentText = currentText;
PrintedErrorMessage = string.Format(errorMessageTemplate, expected, actual);
}
public override void AddToCurrentText(string text)
{
CurrentText = text + CurrentText;
}
}
}

View File

@@ -0,0 +1,25 @@
namespace F4SD.DocuEngine.DocuEngineParser
{
internal class VariableErrorException : DocuEngineParserException
{
private const string errorMessageTemplate = "<<Variable Error | \"{0}\" can't be converted to type \"{1}\">>";
private const string defaultMessage = "Your variable is the wrong type. Get good.";
public VariableErrorException(string currentText) : base(defaultMessage)
{
CurrentText = currentText;
}
public VariableErrorException(string expected, string actual) : base(defaultMessage)
{
PrintedErrorMessage = string.Format(errorMessageTemplate, expected, actual);
}
public VariableErrorException(string currentText, string expected, string actual) : base(defaultMessage)
{
CurrentText = currentText;
PrintedErrorMessage = string.Format(errorMessageTemplate, expected, actual);
}
public override void AddToCurrentText(string text)
{
CurrentText = text + CurrentText;
}
}
}

View File

@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>F4SD.DocuEngine</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="C4IT.F4SD.DisplayFormatting" Version="1.0.0" />
</ItemGroup>
</Project>