diff --git a/Ficdown.Parser.Tests/IntegrationTests.cs b/Ficdown.Parser.Tests/IntegrationTests.cs
index 72af546..1451c0b 100644
--- a/Ficdown.Parser.Tests/IntegrationTests.cs
+++ b/Ficdown.Parser.Tests/IntegrationTests.cs
@@ -1,6 +1,9 @@
namespace Ficdown.Parser.Tests
{
+ using System;
+ using System.IO;
using System.Text;
+ using Render;
using TestStories;
using Xunit;
@@ -12,6 +15,14 @@
var parser = new FicdownParser();
var storyText = Encoding.UTF8.GetString(Resources.TheRobotKing);
var story = parser.ParseStory(storyText);
+ var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "itest_output");
+ if (!Directory.Exists(path)) Directory.CreateDirectory(path);
+ foreach (var file in Directory.GetFiles(path))
+ {
+ File.Delete(file);
+ }
+ var rend = new HtmlRenderer();
+ rend.Render(story, path);
}
}
}
diff --git a/Ficdown.Parser/FicDownParser.cs b/Ficdown.Parser/FicDownParser.cs
index e94b6d2..a88645a 100644
--- a/Ficdown.Parser/FicDownParser.cs
+++ b/Ficdown.Parser/FicDownParser.cs
@@ -36,8 +36,9 @@ namespace Ficdown.Parser
{
var lines = storyText.Split(new[] {"\n", "\r\n"}, StringSplitOptions.None);
var blocks = BlockHandler.ExtractBlocks(lines);
- GameTraverser.Story = BlockHandler.ParseBlocks(blocks);
- return StateResolver.Resolve(GameTraverser.Enumerate());
+ var story = BlockHandler.ParseBlocks(blocks);
+ GameTraverser.Story = story;
+ return StateResolver.Resolve(GameTraverser.Enumerate(), story);
}
}
}
diff --git a/Ficdown.Parser/Ficdown.Parser.csproj b/Ficdown.Parser/Ficdown.Parser.csproj
index b34572a..de2e11f 100644
--- a/Ficdown.Parser/Ficdown.Parser.csproj
+++ b/Ficdown.Parser/Ficdown.Parser.csproj
@@ -43,9 +43,9 @@
-
-
-
+
+
+
@@ -66,6 +66,8 @@
+
+
diff --git a/Ficdown.Parser/Model/Traverser/PageState.cs b/Ficdown.Parser/Model/Player/PageState.cs
similarity index 94%
rename from Ficdown.Parser/Model/Traverser/PageState.cs
rename to Ficdown.Parser/Model/Player/PageState.cs
index 54f2a78..b71290f 100644
--- a/Ficdown.Parser/Model/Traverser/PageState.cs
+++ b/Ficdown.Parser/Model/Player/PageState.cs
@@ -1,4 +1,4 @@
-namespace Ficdown.Parser.Model.Traverser
+namespace Ficdown.Parser.Model.Player
{
using System;
using System.Collections.Generic;
@@ -12,7 +12,7 @@
public State State { get; set; }
public State AffectedState { get; set; }
- public IDictionary StateMatrix { get; set; }
+ public IDictionary StateMatrix { get; set; }
public string Resolved { get; set; }
public IDictionary Links { get; set; }
diff --git a/Ficdown.Parser/Model/Traverser/State.cs b/Ficdown.Parser/Model/Player/State.cs
similarity index 83%
rename from Ficdown.Parser/Model/Traverser/State.cs
rename to Ficdown.Parser/Model/Player/State.cs
index e2ef44b..8ae1f4c 100644
--- a/Ficdown.Parser/Model/Traverser/State.cs
+++ b/Ficdown.Parser/Model/Player/State.cs
@@ -1,4 +1,4 @@
-namespace Ficdown.Parser.Model.Traverser
+namespace Ficdown.Parser.Model.Player
{
using System.Collections;
diff --git a/Ficdown.Parser/Model/Traverser/StateQueueItem.cs b/Ficdown.Parser/Model/Player/StateQueueItem.cs
similarity index 81%
rename from Ficdown.Parser/Model/Traverser/StateQueueItem.cs
rename to Ficdown.Parser/Model/Player/StateQueueItem.cs
index 71afcd4..80d065b 100644
--- a/Ficdown.Parser/Model/Traverser/StateQueueItem.cs
+++ b/Ficdown.Parser/Model/Player/StateQueueItem.cs
@@ -1,4 +1,4 @@
-namespace Ficdown.Parser.Model.Traverser
+namespace Ficdown.Parser.Model.Player
{
using System.Collections.Generic;
diff --git a/Ficdown.Parser/Parser/IStateResolver.cs b/Ficdown.Parser/Parser/IStateResolver.cs
index 6d935a2..b5a5b26 100644
--- a/Ficdown.Parser/Parser/IStateResolver.cs
+++ b/Ficdown.Parser/Parser/IStateResolver.cs
@@ -2,10 +2,11 @@
{
using System.Collections.Generic;
using Model.Parser;
- using Model.Traverser;
+ using Model.Player;
+ using Model.Story;
internal interface IStateResolver
{
- IEnumerable Resolve(IEnumerable pages);
+ IEnumerable Resolve(IEnumerable pages, Story story);
}
}
diff --git a/Ficdown.Parser/Parser/StateResolver.cs b/Ficdown.Parser/Parser/StateResolver.cs
index 66dc2ba..d7e21ff 100644
--- a/Ficdown.Parser/Parser/StateResolver.cs
+++ b/Ficdown.Parser/Parser/StateResolver.cs
@@ -5,13 +5,15 @@
using System.Linq;
using System.Text;
using Model.Parser;
- using Model.Traverser;
+ using Model.Player;
+ using Model.Story;
internal class StateResolver : IStateResolver
{
private static readonly Random _random = new Random((int) DateTime.Now.Ticks);
private readonly IDictionary _pageNames;
private readonly HashSet _usedNames;
+ private Story _story;
public StateResolver()
{
@@ -19,8 +21,9 @@
_usedNames = new HashSet();
}
- public IEnumerable Resolve(IEnumerable pages)
+ public IEnumerable Resolve(IEnumerable pages, Story story)
{
+ _story = story;
return
pages.Select(
page =>
@@ -48,11 +51,22 @@
private string ResolveDescription(PageState page)
{
- var resolved = page.Scene.Description;
+ var resolved = new StringBuilder();
+ resolved.AppendFormat("## {0}\n\n", page.Scene.Name);
- var anchors = Utilities.ParseAnchors(resolved);
+ for (var i = 0; i < page.State.ActionsToShow.Count; i++)
+ {
+ if (page.State.ActionsToShow[i])
+ {
+ resolved.AppendFormat("{0}\n\n", _story.Actions.Single(a => a.Value.Id == i + 1).Value.Description);
+ }
+ }
- resolved = RegexLib.EmptyListItem.Replace(anchors.Aggregate(resolved,
+ var text = resolved.Append(page.Scene.Description).ToString();
+
+ var anchors = Utilities.ParseAnchors(text);
+
+ text = RegexLib.EmptyListItem.Replace(anchors.Aggregate(text,
(current, anchor) =>
current.Replace(anchor.Original,
ResolveAnchor(anchor, GetStateDictionary(page),
@@ -60,10 +74,10 @@
string.Empty);
var seen = page.State.ScenesSeen[page.Scene.Id - 1];
- resolved = !seen
- ? RegexLib.BlockQuoteToken.Replace(resolved, string.Empty)
- : RegexLib.BlockQuotes.Replace(resolved, string.Empty);
- return resolved;
+ text = !seen
+ ? RegexLib.BlockQuoteToken.Replace(text, string.Empty)
+ : RegexLib.BlockQuotes.Replace(text, string.Empty);
+ return text;
}
private IDictionary GetStateDictionary(PageState page)
diff --git a/Ficdown.Parser/Player/GameTraverser.cs b/Ficdown.Parser/Player/GameTraverser.cs
index 4f4d0af..557dc0d 100644
--- a/Ficdown.Parser/Player/GameTraverser.cs
+++ b/Ficdown.Parser/Player/GameTraverser.cs
@@ -2,8 +2,8 @@
{
using System.Collections.Generic;
using System.Linq;
+ using Model.Player;
using Model.Story;
- using Model.Traverser;
using Parser;
internal class GameTraverser : IGameTraverser
@@ -12,6 +12,7 @@
private Queue _processingQueue;
private IDictionary _processed;
private IDictionary _compressed;
+ private IDictionary _actionMatrix;
private Story _story;
public Story Story
@@ -20,6 +21,7 @@
set
{
_story = value;
+ _actionMatrix = _story.Actions.ToDictionary(a => a.Value.Id, a => a.Value);
_manager = new StateManager(_story);
_processingQueue = new Queue();
_processed = new Dictionary();
@@ -65,11 +67,23 @@
return _compressed.Values;
}
+ private IEnumerable GetActionsForPage(PageState page)
+ {
+ var actions = new List();
+ for (var i = 0; i < page.State.ActionsToShow.Count; i++)
+ {
+ if (page.State.ActionsToShow[i]) actions.Add(_actionMatrix[i + 1]);
+ }
+ return actions;
+ }
+
private void ProcessState(StateQueueItem currentState)
{
var states = new HashSet();
- var anchors = Utilities.ParseAnchors(currentState.Page.Scene.Description);
+ var anchors = Utilities.ParseAnchors(currentState.Page.Scene.Description).ToList();
+ foreach (var action in GetActionsForPage(currentState.Page))
+ anchors.AddRange(Utilities.ParseAnchors(action.Description));
var conditionals =
anchors.SelectMany(
a => a.Href.Conditions != null ? a.Href.Conditions.Select(c => c.Key) : new string[] {})
@@ -80,6 +94,9 @@
foreach (var affected in currentState.AffectedStates)
{
// signal to previous scenes that this scene's used conditionals are important
+ if(currentState.Page.Scene.Conditions != null)
+ foreach (var conditional in currentState.Page.Scene.Conditions)
+ _manager.ToggleStateOn(affected, conditional.Key);
foreach (var conditional in conditionals) _manager.ToggleStateOn(affected, conditional);
// signal to previous scenes if this scene has first-seen text
diff --git a/Ficdown.Parser/Player/IGameTraverser.cs b/Ficdown.Parser/Player/IGameTraverser.cs
index 22d2254..f390402 100644
--- a/Ficdown.Parser/Player/IGameTraverser.cs
+++ b/Ficdown.Parser/Player/IGameTraverser.cs
@@ -1,8 +1,8 @@
namespace Ficdown.Parser.Player
{
using System.Collections.Generic;
+ using Model.Player;
using Model.Story;
- using Model.Traverser;
internal interface IGameTraverser
{
diff --git a/Ficdown.Parser/Player/StateManager.cs b/Ficdown.Parser/Player/StateManager.cs
index ce1565e..dbf1a3a 100644
--- a/Ficdown.Parser/Player/StateManager.cs
+++ b/Ficdown.Parser/Player/StateManager.cs
@@ -5,8 +5,8 @@
using System.Collections.Generic;
using System.Linq;
using Model.Parser;
+ using Model.Player;
using Model.Story;
- using Model.Traverser;
using Parser;
internal class StateManager
diff --git a/Ficdown.Parser/Render/HtmlRenderer.cs b/Ficdown.Parser/Render/HtmlRenderer.cs
new file mode 100644
index 0000000..c9e4712
--- /dev/null
+++ b/Ficdown.Parser/Render/HtmlRenderer.cs
@@ -0,0 +1,33 @@
+namespace Ficdown.Parser.Render
+{
+ using System.Collections.Generic;
+ using System.IO;
+ using MarkdownSharp;
+ using Model.Parser;
+ using Model.Story;
+ using Parser;
+
+ internal class HtmlRenderer : IRenderer
+ {
+ private readonly Markdown _md;
+
+ public HtmlRenderer()
+ {
+ _md = new Markdown();
+ }
+
+ public void Render(IEnumerable pages, string outPath)
+ {
+ foreach (var page in pages)
+ {
+ var content = page.Content;
+ foreach (var anchor in Utilities.ParseAnchors(page.Content))
+ {
+ var newAnchor = string.Format("[{0}]({1}.html)", anchor.Text, anchor.Href.Target);
+ content = content.Replace(anchor.Original, newAnchor);
+ }
+ File.WriteAllText(Path.Combine(outPath, string.Format("{0}.html", page.Name)), _md.Transform(content));
+ }
+ }
+ }
+}
diff --git a/Ficdown.Parser/Render/IRenderer.cs b/Ficdown.Parser/Render/IRenderer.cs
new file mode 100644
index 0000000..4a1c9db
--- /dev/null
+++ b/Ficdown.Parser/Render/IRenderer.cs
@@ -0,0 +1,11 @@
+namespace Ficdown.Parser.Render
+{
+ using System.Collections.Generic;
+ using Model.Parser;
+ using Model.Story;
+
+ internal interface IRenderer
+ {
+ void Render(IEnumerable pages, string outPath);
+ }
+}