FIL-4 Refactored script parsing to retain isolated comments as a new ItemFilterBlockComment type - UI still needs reworking with new templates and such.

This commit is contained in:
Ben Wallis
2017-05-20 18:14:28 +01:00
parent 797c911bb5
commit 4def27c49d
18 changed files with 273 additions and 108 deletions

View File

@@ -29,6 +29,22 @@ namespace Filtration.Parser.Services
_blockGroupHierarchyBuilder = blockGroupHierarchyBuilder;
}
// Converts a string into an ItemFilterCommentBlock maintaining newlines and spaces but removing # characters
public IItemFilterCommentBlock TranslateStringToItemFilterCommentBlock(string inputString)
{
var itemFilterCommentBlock = new ItemFilterCommentBlock();
foreach (var line in new LineReader(() => new StringReader(inputString)))
{
var trimmedLine = line.TrimStart(' ').TrimStart('#');
itemFilterCommentBlock.Comment += trimmedLine + Environment.NewLine;
}
itemFilterCommentBlock.Comment = itemFilterCommentBlock.Comment.TrimEnd('\r', '\n');
return itemFilterCommentBlock;
}
// This method converts a string into a ItemFilterBlock. This is used for pasting ItemFilterBlocks
// and reading ItemFilterScripts from a file.
public IItemFilterBlock TranslateStringToItemFilterBlock(string inputString, IItemFilterScriptSettings itemFilterScriptSettings)
@@ -39,16 +55,6 @@ namespace Filtration.Parser.Services
foreach (var line in new LineReader(() => new StringReader(inputString)))
{
if (line.StartsWith(@"# Section:"))
{
var section = new ItemFilterSection
{
Description = line.Substring(line.IndexOf(":", StringComparison.Ordinal) + 1).Trim()
};
return section;
}
if (line.StartsWith(@"#") && !showHideFound)
{
block.Description = line.TrimStart('#').TrimStart(' ');
@@ -205,6 +211,7 @@ namespace Filtration.Parser.Services
switch (matches.Count)
{
case 1:
{
if (matches[0].Success)
{
var blockItemValue = new SoundBlockItem
@@ -215,7 +222,9 @@ namespace Filtration.Parser.Services
block.BlockItems.Add(blockItemValue);
}
break;
}
case 2:
{
if (matches[0].Success && matches[1].Success)
{
var blockItemValue = new SoundBlockItem
@@ -226,6 +235,7 @@ namespace Filtration.Parser.Services
block.BlockItems.Add(blockItemValue);
}
break;
}
}
break;
}
@@ -436,7 +446,8 @@ namespace Filtration.Parser.Services
// to the clipboard, and when saving a ItemFilterScript.
public string TranslateItemFilterBlockToString(IItemFilterBlock block)
{
if (block.GetType() == typeof (ItemFilterSection))
// TODO: fix
if (block.GetType() == typeof (ItemFilterCommentBlock))
{
return "# Section: " + block.Description;
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using Filtration.Common.Utilities;
using Filtration.ObjectModel;
@@ -10,6 +11,26 @@ using Filtration.Properties;
namespace Filtration.Parser.Services
{
internal class ItemFilterBlockBoundary
{
public ItemFilterBlockBoundary(int startLine, ItemFilterBlockBoundaryType itemFilterBlockBoundaryType)
{
StartLine = startLine;
BoundaryType = itemFilterBlockBoundaryType;
}
public int StartLine { get; set; }
public ItemFilterBlockBoundaryType BoundaryType { get; set; }
}
internal enum ItemFilterBlockBoundaryType
{
ItemFilterBlock,
CommentBlock
}
internal class ItemFilterScriptTranslator : IItemFilterScriptTranslator
{
private readonly IItemFilterBlockTranslator _blockTranslator;
@@ -98,12 +119,12 @@ namespace Filtration.Parser.Services
var lines = Regex.Split(inputString, "\r\n|\r|\n");
// Process the script header
for (var i = 0; i < conditionBoundaries.First.Value; i++)
for (var i = 0; i < conditionBoundaries.First.Value.StartLine; i++)
{
if (lines[i].StartsWith("#"))
{
script.Description += lines[i].Substring(1).Trim(' ') + Environment.NewLine;
}
}
}
if (!string.IsNullOrEmpty(script.Description))
@@ -115,43 +136,85 @@ namespace Filtration.Parser.Services
// and add that object to the ItemFilterBlocks list
for (var boundary = conditionBoundaries.First; boundary != null; boundary = boundary.Next)
{
var begin = boundary.Value;
var end = boundary.Next?.Value ?? lines.Length;
var begin = boundary.Value.StartLine;
var end = boundary.Next?.Value.StartLine ?? lines.Length;
var block = new string[end - begin];
Array.Copy(lines, begin, block, 0, end - begin);
var blockString = string.Join("\r\n", block);
script.ItemFilterBlocks.Add(_blockTranslator.TranslateStringToItemFilterBlock(blockString, script.ItemFilterScriptSettings));
if (boundary.Value.BoundaryType == ItemFilterBlockBoundaryType.ItemFilterBlock)
{
script.ItemFilterBlocks.Add(_blockTranslator.TranslateStringToItemFilterBlock(blockString, script.ItemFilterScriptSettings));
}
else
{
script.ItemFilterBlocks.Add(_blockTranslator.TranslateStringToItemFilterCommentBlock(blockString));
}
}
_blockGroupHierarchyBuilder.Cleanup();
return script;
}
private static LinkedList<int> IdentifyBlockBoundaries(string inputString)
private static LinkedList<ItemFilterBlockBoundary> IdentifyBlockBoundaries(string inputString)
{
var blockBoundaries = new LinkedList<int>();
var blockBoundaries = new LinkedList<ItemFilterBlockBoundary>();
var previousLine = string.Empty;
var currentLine = 0;
var currentLine = -1;
var currentItemFilterBlockBoundary = new ItemFilterBlockBoundary(1, ItemFilterBlockBoundaryType.CommentBlock);
foreach (var line in new LineReader(() => new StringReader(inputString)))
{
currentLine++;
var trimmedLine = line.Trim(' ');
if (trimmedLine.StartsWith("Show") || trimmedLine.StartsWith("Hide") ||
trimmedLine.StartsWith("# Section:"))
if (string.IsNullOrWhiteSpace(trimmedLine))
{
previousLine = line;
continue;
}
// A line starting with a comment when we're inside a ItemFilterBlock boundary represents the end of that block
// as ItemFilterBlocks cannot have comment lines after the block description
if (trimmedLine.StartsWith("#") && currentItemFilterBlockBoundary?.BoundaryType == ItemFilterBlockBoundaryType.ItemFilterBlock)
{
blockBoundaries.AddLast(currentItemFilterBlockBoundary);
currentItemFilterBlockBoundary = new ItemFilterBlockBoundary(currentLine, ItemFilterBlockBoundaryType.CommentBlock);
}
// A line starting with a comment where the previous line was null represents the start of a new comment (unless we're on the first
// line in which case it's not a new comment).
else if (trimmedLine.StartsWith("#") && string.IsNullOrWhiteSpace(previousLine) && currentLine > 0)
{
if (blockBoundaries.Count > 0)
{
blockBoundaries.AddLast(currentItemFilterBlockBoundary);
}
currentItemFilterBlockBoundary = new ItemFilterBlockBoundary(currentLine, ItemFilterBlockBoundaryType.CommentBlock);
}
else if (trimmedLine.StartsWith("Show") || trimmedLine.StartsWith("Hide"))
{
// If the line previous to the Show or Hide line is a comment then we should include that in the block
// as it represents the block description.
// currentLine > 2 caters for an edge case where the script description is a single line and the first
// block has no description. This prevents the script description from being assigned to the first block's description.
blockBoundaries.AddLast(previousLine.StartsWith("#") && !previousLine.StartsWith("# Section:") &&
currentLine > 2
? currentLine - 2
: currentLine - 1);
if (!(currentItemFilterBlockBoundary.StartLine == currentLine - 1 && currentItemFilterBlockBoundary.BoundaryType == ItemFilterBlockBoundaryType.CommentBlock))
{
blockBoundaries.AddLast(currentItemFilterBlockBoundary);
}
currentItemFilterBlockBoundary = new ItemFilterBlockBoundary(previousLine.StartsWith("#") && currentLine > 2 ? currentLine - 1 : currentLine,
ItemFilterBlockBoundaryType.ItemFilterBlock);
}
previousLine = line;
}
if (blockBoundaries.Last.Value != currentItemFilterBlockBoundary)
{
blockBoundaries.AddLast(currentItemFilterBlockBoundary);
}
return blockBoundaries;
}
@@ -178,7 +241,7 @@ namespace Filtration.Parser.Services
// ReSharper disable once LoopCanBeConvertedToQuery
foreach (var block in script.ItemFilterBlocks)
{
outputString += _blockTranslator.TranslateItemFilterBlockToString(block) + Environment.NewLine;
outputString += _blockTranslator.TranslateItemFilterBlockToString(block as ItemFilterBlock) + Environment.NewLine;
if (Settings.Default.ExtraLineBetweenBlocks)
{