removed negative condition checking, very little gained for so much additional complexity

This commit is contained in:
Rudis Muiznieks 2014-07-01 01:51:08 -05:00
parent 154410fb54
commit d72b393e21
11 changed files with 59 additions and 61 deletions

View File

@ -61,7 +61,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <None Include="packages.config" />
<None Include="TestStories\the-robot-king.md" /> <None Include="TestStories\TheRobotKing.md" />
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup />
<ItemGroup> <ItemGroup>

View File

@ -1,6 +1,7 @@
namespace Ficdown.Parser.Tests namespace Ficdown.Parser.Tests
{ {
using System; using System;
using System.Linq;
using System.Text; using System.Text;
using ServiceStack.Text; using ServiceStack.Text;
using TestStories; using TestStories;
@ -12,9 +13,11 @@
public void CanParseValidStoryFile() public void CanParseValidStoryFile()
{ {
var parser = new FicdownParser(); var parser = new FicdownParser();
var storyText = Encoding.UTF8.GetString(Resources.the_robot_king); var storyText = Encoding.UTF8.GetString(Resources.TheRobotKing);
var story = parser.ParseStory(storyText); var story = parser.ParseStory(storyText);
Assert.NotNull(story); Assert.NotNull(story);
Assert.Equal("The Robot King", story.Name);
Assert.Equal("Robot Cave", story.Scenes[story.FirstScene].First().Name);
Console.WriteLine(story.Dump()); Console.WriteLine(story.Dump());
} }
} }

View File

@ -41,6 +41,7 @@
} }
}); });
sl.ExpandScenes(story); sl.ExpandScenes(story);
Console.WriteLine(story.Dump());
Assert.Equal(2, story.Scenes["test-scene"].Count); Assert.Equal(2, story.Scenes["test-scene"].Count);
Scene passed = null, failed = null; Scene passed = null, failed = null;
Assert.DoesNotThrow(() => Assert.DoesNotThrow(() =>
@ -57,22 +58,6 @@
Assert.NotNull(failed); Assert.NotNull(failed);
} }
[Fact]
public void NegativeConditionalAnchorGetsReplacedCorrectly()
{
var sl = new SceneLinker();
var story = MockStoryWithScenes(new[]
{
new Scene
{
Name = "Test Scene",
Description = "Test [passed|failed](?!test-condition) text."
}
});
sl.ExpandScenes(story);
Console.WriteLine(story.Dump());
}
[Fact] [Fact]
public void MultipleConditionalAnchorsGetReplacedCorrectly() public void MultipleConditionalAnchorsGetReplacedCorrectly()
{ {
@ -88,6 +73,24 @@
}); });
sl.ExpandScenes(story); sl.ExpandScenes(story);
Console.WriteLine(story.Dump()); Console.WriteLine(story.Dump());
Assert.Equal(4, story.Scenes["test-scene"].Count);
Assert.Equal(
story.Scenes["test-scene"].Select(s => s.Conditions == null ? null : s.Conditions.ToArray()).ToArray(),
new[]
{
null, new[] {"test1-condition"}, new[] {"test2-condition"},
new[] {"test1-condition", "test2-condition"}
});
Assert.False(
story.Scenes["test-scene"].Any(
s =>
s.Conditions != null && s.Conditions.Contains("test1-condition") &&
s.Description.Contains("Test1 failed1.")));
Assert.False(
story.Scenes["test-scene"].Any(
s =>
s.Conditions != null && s.Conditions.Contains("test2-condition") &&
s.Description.Contains("Test2 failed2.")));
} }
} }
} }

View File

@ -63,9 +63,9 @@ namespace Ficdown.Parser.Tests.TestStories {
/// <summary> /// <summary>
/// Looks up a localized resource of type System.Byte[]. /// Looks up a localized resource of type System.Byte[].
/// </summary> /// </summary>
internal static byte[] the_robot_king { internal static byte[] TheRobotKing {
get { get {
object obj = ResourceManager.GetObject("the_robot_king", resourceCulture); object obj = ResourceManager.GetObject("TheRobotKing", resourceCulture);
return ((byte[])(obj)); return ((byte[])(obj));
} }
} }

View File

@ -118,7 +118,7 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="the_robot_king" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="TheRobotKing" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>the-robot-king.md;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>therobotking.md;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data> </data>
</root> </root>

View File

@ -15,8 +15,8 @@ Your cave only has one tiny window, and through it you can see [the sun shining
**What do you want to do?** **What do you want to do?**
- [Go outside and start walking to the palace.](/outside) - [Go outside and start walking to the palace.](/outside)
- [Wait for it to stop raining.](?!stopped-raining#stopped-raining) - [|Wait for it to stop raining.](?stopped-raining#stopped-raining)
- [Put on your raincoat.](?!raincoat#raincoat) - [|Put on your raincoat.](?raincoat#raincoat)
### Raincoat ### Raincoat
@ -26,7 +26,7 @@ You take your raincoat and put it on. It fits perfectly!
It feels like hours, but it finally stops raining. You hope you won't be late for your new job! It feels like hours, but it finally stops raining. You hope you won't be late for your new job!
## [Outside](?!raincoat&!stopped-raining) ## Outside
> You step through the door and feel the water flowing over your metal body. Brrr! That's cold! You start to think that maybe getting your raincoat would be a good idea. This is just the kind of rain that might turn you into a rusty robot statue if you stay in it too long. > You step through the door and feel the water flowing over your metal body. Brrr! That's cold! You start to think that maybe getting your raincoat would be a good idea. This is just the kind of rain that might turn you into a rusty robot statue if you stay in it too long.
@ -37,7 +37,7 @@ You're standing on your front porch in the pouring rain. You need to get to the
- [Continue walking to the palace.](/rusted) - [Continue walking to the palace.](/rusted)
- [Go back into your cave.](/robot-cave) - [Go back into your cave.](/robot-cave)
## Outside ## [Outside](?stopped-raining)
You step through the door and feel the early afternoon sun warming your metal body. It feels good, but you were supposed to start your new job early in the morning! You step through the door and feel the early afternoon sun warming your metal body. It feels good, but you were supposed to start your new job early in the morning!
@ -57,7 +57,7 @@ You will have a long time to think about your mistake while you wait for another
**You have turned into a rusty robot statue!** **You have turned into a rusty robot statue!**
## [Outside](?raincoat&!stopped-raining) ## [Outside](?raincoat)
You head out the door and into the rain. It's a good thing you put on your raincoat, because it's just the kind of rain that would probably turn you into a rusty robot statue if you stayed in it for too long. You head out the door and into the rain. It's a good thing you put on your raincoat, because it's just the kind of rain that would probably turn you into a rusty robot statue if you stayed in it for too long.
@ -67,10 +67,10 @@ The palace guard looks you up and down. "What do you want?" he asks.
**What will you tell him?** **What will you tell him?**
- ["I'm the new janitor-bot!"](/palace-entrance#new-job) - ["I'm the new janitor-bot!"](/palace-gate#new-job)
- ["I'd like a tour of the palace!"](/palace-entrance) - ["I'd like a tour of the palace!"](/palace-gate)
## Palace Entrance ## Palace Gate
The robot guard looks at you and [nods|frowns](?new-job). "[Oh yeah, they told me to expect you. You're supposed to be starting today right?|We don't do tours on weekdays. Hey, aren't you the new janitor-bot who's starting today?](?new-job)" The robot guard looks at you and [nods|frowns](?new-job). "[Oh yeah, they told me to expect you. You're supposed to be starting today right?|We don't do tours on weekdays. Hey, aren't you the new janitor-bot who's starting today?](?new-job)"
@ -117,13 +117,13 @@ You walk into the hall that leads to the living quarters, and find a gate blocki
You're standing in the basement where new employees can pick up their uniforms and learn what their jobs are for the day. You're standing in the basement where new employees can pick up their uniforms and learn what their jobs are for the day.
[The Master Janitor Robot is pacing back and forth here, muttering to himself.|There is a funny looking robot here pacing back and forth, muttering to himself. That must be the Master Janitor Robot. When he notices you, he stops muttering and stares at you with crazy eyes.](#talked-to-master) [The Master Janitor Robot is pacing back and forth here, muttering to himself.|There is a funny looking robot here pacing back and forth, muttering to himself. That must be the Master Janitor Robot. When he notices you, he stops muttering and stares at you with crazy eyes.](?talked-to-master)
**What will you do?** **What will you do?**
- [Go back upstairs.](/palace-entrance) - [Go back upstairs.](/palace-entrance)
- [Ask the Master Janitor Robot what he's muttering about.](#talked-to-master+muttering) - [Ask the Master Janitor Robot what he's muttering about.](#talked-to-master+muttering)
- [Ask the Master Janitor Robot about your uniform.](#talked-to-master+uniform) - [|Ask the Master Janitor Robot about your uniform.](?uniform#talked-to-master+uniform)
- [Ask the Master Janitor Robot about the gate upstairs.](?tried-gate#talked-to-master+about-the-gate) - [Ask the Master Janitor Robot about the gate upstairs.](?tried-gate#talked-to-master+about-the-gate)
- [Ask the Master Janitor Robot about your job.](?uniform#started-job) - [Ask the Master Janitor Robot about your job.](?uniform#started-job)
@ -145,7 +145,7 @@ He walks to a box in the corner and pulls out a blue janitor's uniform, then han
### Started Job ### Started Job
"Ready to get going?" says the Master Janitor Robot. He continues before you have a chance to answer. "Good, good. Your first job will be to clean room 13 in the living quarters. That's where the Robot King keeps all of his spare robes and crowns. There's a janitor's closet right next to that room where you can get a mop to clean the floors, and a duster to dust off the crowns." ["Like I said before, your|"Ready to get going?" says the Master Janitor Robot. He continues before you have a chance to answer. "Good, good. Your](?started-job) first job will be to clean room 13 in the living quarters. That's where the Robot King keeps all of his spare robes and crowns. There's a janitor's closet right next to that room where you can get a mop to clean the floors, and a duster to dust off the crowns."
The Master Janitor Robot scratches his chin for a moment, then resumes pacing back and forth and muttering to himself. The Master Janitor Robot scratches his chin for a moment, then resumes pacing back and forth and muttering to himself.
@ -155,7 +155,7 @@ You head into the hallway that leads to the living quarters and come to a large
You notice with some alarm that there's no scanner on the inside of the gate. You don't know how to get back out! You notice with some alarm that there's no scanner on the inside of the gate. You don't know how to get back out!
## [Living Quarters](?uniform&!job-started) ## [Living Quarters](?uniform)
That's when you realize that you never asked the Master Janitor Bot what your job here was. You just took your uniform and left! That's when you realize that you never asked the Master Janitor Bot what your job here was. You just took your uniform and left!

View File

@ -94,17 +94,11 @@
Assert.Contains("condition-state", conditions); Assert.Contains("condition-state", conditions);
Assert.Null(toggles); Assert.Null(toggles);
Utilities.ParseHref("?!condition-state", out target, out conditions, out toggles); Utilities.ParseHref("?condition-1&condition-2", out target, out conditions, out toggles);
Assert.Null(target);
Assert.Equal(1, conditions.Count);
Assert.Contains("!condition-state", conditions);
Assert.Null(toggles);
Utilities.ParseHref("?condition-1&!condition-2", out target, out conditions, out toggles);
Assert.Null(target); Assert.Null(target);
Assert.Equal(2, conditions.Count); Assert.Equal(2, conditions.Count);
Assert.Contains("condition-1", conditions); Assert.Contains("condition-1", conditions);
Assert.Contains("!condition-2", conditions); Assert.Contains("condition-2", conditions);
Assert.Null(toggles); Assert.Null(toggles);
} }
@ -151,13 +145,14 @@
Assert.Equal(1, toggles.Count); Assert.Equal(1, toggles.Count);
Assert.Contains("toggle-state", toggles); Assert.Contains("toggle-state", toggles);
Utilities.ParseHref("?!condition-one&condition-two#toggle-state", out target, out conditions, out toggles); Utilities.ParseHref("?condition-one&condition-two#toggle-one+toggle-two", out target, out conditions, out toggles);
Assert.Null(target); Assert.Null(target);
Assert.Equal(2, conditions.Count); Assert.Equal(2, conditions.Count);
Assert.Contains("!condition-one", conditions); Assert.Contains("condition-one", conditions);
Assert.Contains("condition-two", conditions); Assert.Contains("condition-two", conditions);
Assert.Equal(1, toggles.Count); Assert.Equal(2, toggles.Count);
Assert.Contains("toggle-state", toggles); Assert.Contains("toggle-one", toggles);
Assert.Contains("toggle-two", toggles);
} }
} }
} }

View File

@ -90,7 +90,7 @@
var sceneName = RegexLib.Anchors.Match(block.Name); var sceneName = RegexLib.Anchors.Match(block.Name);
if (sceneName.Success) if (sceneName.Success)
{ {
scene.Name = sceneName.Groups["text"].Value; scene.Name = sceneName.Groups["text"].Value.Trim();
IList<string> conditions; IList<string> conditions;
try try
{ {

View File

@ -17,7 +17,7 @@
private const string RegexValidName = @"[a-zA-Z](-?[a-zA-Z0-9])*"; private const string RegexValidName = @"[a-zA-Z](-?[a-zA-Z0-9])*";
private static readonly string RegexHrefTarget = string.Format(@"\/({0})", RegexValidName); private static readonly string RegexHrefTarget = string.Format(@"\/({0})", RegexValidName);
private static readonly string RegexHrefConditions = string.Format(@"\?((!?{0})(&!?{0})*)?", RegexValidName); private static readonly string RegexHrefConditions = string.Format(@"\?(({0})(&{0})*)?", RegexValidName);
private static readonly string RegexHrefToggles = string.Format(@"#({0})(\+{0})*", RegexValidName); private static readonly string RegexHrefToggles = string.Format(@"#({0})(\+{0})*", RegexValidName);
public static Regex Href = public static Regex Href =

View File

@ -67,7 +67,6 @@
// make sure this is actually unique // make sure this is actually unique
if (uniques.Any(u => u.Intersect(conditions).Count() == conditions.Count)) return; if (uniques.Any(u => u.Intersect(conditions).Count() == conditions.Count)) return;
uniques.Add(conditions); uniques.Add(conditions);
// we need to treat this unioned with all other existing uniques as another potential unique // we need to treat this unioned with all other existing uniques as another potential unique
@ -87,11 +86,7 @@
Utilities.ParseHref(anchor.Groups["href"].Value, out target, out conditions, out toggles); Utilities.ParseHref(anchor.Groups["href"].Value, out target, out conditions, out toggles);
if (conditions != null) if (conditions != null)
{ {
var satisfied = scene.Conditions == null var satisfied = scene.Conditions != null && conditions.All(c => scene.Conditions.Contains(c));
? conditions.All(c => c.StartsWith("!"))
: conditions.All(
c => scene.Conditions.Contains(c) ||
(c.StartsWith("!") && !scene.Conditions.Contains(c)));
var text = anchor.Groups["text"].Value; var text = anchor.Groups["text"].Value;
var alts = RegexLib.ConditionalText.Match(text); var alts = RegexLib.ConditionalText.Match(text);
@ -103,17 +98,18 @@
RegexLib.EscapeChar.Replace(satisfied ? alts.Groups["true"].Value : alts.Groups["false"].Value, RegexLib.EscapeChar.Replace(satisfied ? alts.Groups["true"].Value : alts.Groups["false"].Value,
string.Empty); string.Empty);
// if there's no target or toggles, replace the whole anchor // if there's no target or toggles, or the replace text is an empty string, replace the whole anchor
if (target == null && toggles == null) if (string.IsNullOrEmpty(replace) || (target == null && toggles == null))
{ {
scene.Description = scene.Description.Replace(anchor.Groups["anchor"].Value, replace); scene.Description = scene.Description.Replace(anchor.Groups["anchor"].Value, replace);
} }
// if there's a target or toggles, replace the text and remove the conditions on the anchor // if there's a target or toggles, replace the text and remove the conditions on the anchor
else else
{ {
var parsedHref = RegexLib.Href.Match(anchor.Groups["href"].Value);
scene.Description = scene.Description.Replace(anchor.Groups["anchor"].Value, scene.Description = scene.Description.Replace(anchor.Groups["anchor"].Value,
string.Format("[{0}]({1}{2})", replace, anchor.Groups["target"].Value, string.Format("[{0}]({1}{2})", replace, parsedHref.Groups["target"].Value,
anchor.Groups["toggles"].Value)); parsedHref.Groups["toggles"].Value));
} }
} }

View File

@ -1,5 +1,6 @@
namespace Ficdown.Parser namespace Ficdown.Parser
{ {
using System;
using Engine; using Engine;
using Model.Story; using Model.Story;
@ -22,7 +23,7 @@
public Story ParseStory(string storyText) public Story ParseStory(string storyText)
{ {
var lines = storyText.Split('\n'); var lines = storyText.Split(new[] {"\n", "\r\n"}, StringSplitOptions.None);
var blocks = BlockHandler.ExtractBlocks(lines); var blocks = BlockHandler.ExtractBlocks(lines);
var story = BlockHandler.ParseBlocks(blocks); var story = BlockHandler.ParseBlocks(blocks);
SceneLinker.ExpandScenes(story); SceneLinker.ExpandScenes(story);