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.
228 lines
9.3 KiB
C#
228 lines
9.3 KiB
C#
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));
|
|
}
|
|
}
|
|
}
|
|
}
|