removed negative condition checking, very little gained for so much additional complexity
This commit is contained in:
parent
154410fb54
commit
d72b393e21
11 changed files with 59 additions and 61 deletions
|
@ -61,7 +61,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="TestStories\the-robot-king.md" />
|
||||
<None Include="TestStories\TheRobotKing.md" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
namespace Ficdown.Parser.Tests
|
||||
{
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ServiceStack.Text;
|
||||
using TestStories;
|
||||
|
@ -12,9 +13,11 @@
|
|||
public void CanParseValidStoryFile()
|
||||
{
|
||||
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);
|
||||
Assert.NotNull(story);
|
||||
Assert.Equal("The Robot King", story.Name);
|
||||
Assert.Equal("Robot Cave", story.Scenes[story.FirstScene].First().Name);
|
||||
Console.WriteLine(story.Dump());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
}
|
||||
});
|
||||
sl.ExpandScenes(story);
|
||||
Console.WriteLine(story.Dump());
|
||||
Assert.Equal(2, story.Scenes["test-scene"].Count);
|
||||
Scene passed = null, failed = null;
|
||||
Assert.DoesNotThrow(() =>
|
||||
|
@ -57,22 +58,6 @@
|
|||
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]
|
||||
public void MultipleConditionalAnchorsGetReplacedCorrectly()
|
||||
{
|
||||
|
@ -88,6 +73,24 @@
|
|||
});
|
||||
sl.ExpandScenes(story);
|
||||
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.")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,9 +63,9 @@ namespace Ficdown.Parser.Tests.TestStories {
|
|||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] the_robot_king {
|
||||
internal static byte[] TheRobotKing {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("the_robot_king", resourceCulture);
|
||||
object obj = ResourceManager.GetObject("TheRobotKing", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@
|
|||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<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">
|
||||
<value>the-robot-king.md;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<data name="TheRobotKing" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>therobotking.md;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
</root>
|
|
@ -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?**
|
||||
|
||||
- [Go outside and start walking to the palace.](/outside)
|
||||
- [Wait for it to stop raining.](?!stopped-raining#stopped-raining)
|
||||
- [Put on your raincoat.](?!raincoat#raincoat)
|
||||
- [|Wait for it to stop raining.](?stopped-raining#stopped-raining)
|
||||
- [|Put on your 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!
|
||||
|
||||
## [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.
|
||||
|
||||
|
@ -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)
|
||||
- [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!
|
||||
|
||||
|
@ -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!**
|
||||
|
||||
## [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.
|
||||
|
||||
|
@ -67,10 +67,10 @@ The palace guard looks you up and down. "What do you want?" he asks.
|
|||
|
||||
**What will you tell him?**
|
||||
|
||||
- ["I'm the new janitor-bot!"](/palace-entrance#new-job)
|
||||
- ["I'd like a tour of the palace!"](/palace-entrance)
|
||||
- ["I'm the new janitor-bot!"](/palace-gate#new-job)
|
||||
- ["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)"
|
||||
|
||||
|
@ -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.
|
||||
|
||||
[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?**
|
||||
|
||||
- [Go back upstairs.](/palace-entrance)
|
||||
- [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 your job.](?uniform#started-job)
|
||||
|
||||
|
@ -141,11 +141,11 @@ He walks to a box in the corner and pulls out a blue janitor's uniform, then han
|
|||
|
||||
### About the Gate
|
||||
|
||||
"Ahh, yes, the gate," says the Master Janitor Robot. "Quite a clever contraption. There's a scanner attached that looks for a special device that's sewn into the [uniform I gave you|uniform that employees here wear](?uniform).[ As I said, you'll want to head up there now to start cleaning room 13.](?started-job)"
|
||||
"Ahh, yes, the gate," says the Master Janitor Robot. "Quite a clever contraption. There's a scanner attached that looks for a special device that's sewn into the [uniform I gave you|uniform that employees here wear](?uniform). [As I said, you'll want to head up there now to start cleaning room 13.](?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.
|
||||
|
||||
|
@ -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!
|
||||
|
||||
## [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!
|
||||
|
||||
|
@ -167,4 +167,4 @@ That's no problem though, because you already know what your job is. You continu
|
|||
|
||||
You open the closet and grab the mop and duster. You're so excited! Your first day as a janitor working for a Robot King that looks just like you, and you are about to enter a room containing all of his spare robes and crowns. What fun!
|
||||
|
||||
**You have reached the end of the intro to The Robot King.**
|
||||
**You have reached the end of the intro to The Robot King.**
|
|
@ -94,17 +94,11 @@
|
|||
Assert.Contains("condition-state", conditions);
|
||||
Assert.Null(toggles);
|
||||
|
||||
Utilities.ParseHref("?!condition-state", 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);
|
||||
Utilities.ParseHref("?condition-1&condition-2", out target, out conditions, out toggles);
|
||||
Assert.Null(target);
|
||||
Assert.Equal(2, conditions.Count);
|
||||
Assert.Contains("condition-1", conditions);
|
||||
Assert.Contains("!condition-2", conditions);
|
||||
Assert.Contains("condition-2", conditions);
|
||||
Assert.Null(toggles);
|
||||
}
|
||||
|
||||
|
@ -151,13 +145,14 @@
|
|||
Assert.Equal(1, toggles.Count);
|
||||
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.Equal(2, conditions.Count);
|
||||
Assert.Contains("!condition-one", conditions);
|
||||
Assert.Contains("condition-one", conditions);
|
||||
Assert.Contains("condition-two", conditions);
|
||||
Assert.Equal(1, toggles.Count);
|
||||
Assert.Contains("toggle-state", toggles);
|
||||
Assert.Equal(2, toggles.Count);
|
||||
Assert.Contains("toggle-one", toggles);
|
||||
Assert.Contains("toggle-two", toggles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
var sceneName = RegexLib.Anchors.Match(block.Name);
|
||||
if (sceneName.Success)
|
||||
{
|
||||
scene.Name = sceneName.Groups["text"].Value;
|
||||
scene.Name = sceneName.Groups["text"].Value.Trim();
|
||||
IList<string> conditions;
|
||||
try
|
||||
{
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
private const string RegexValidName = @"[a-zA-Z](-?[a-zA-Z0-9])*";
|
||||
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);
|
||||
|
||||
public static Regex Href =
|
||||
|
|
|
@ -66,7 +66,6 @@
|
|||
|
||||
// make sure this is actually unique
|
||||
if (uniques.Any(u => u.Intersect(conditions).Count() == conditions.Count)) return;
|
||||
|
||||
|
||||
uniques.Add(conditions);
|
||||
|
||||
|
@ -87,11 +86,7 @@
|
|||
Utilities.ParseHref(anchor.Groups["href"].Value, out target, out conditions, out toggles);
|
||||
if (conditions != null)
|
||||
{
|
||||
var satisfied = scene.Conditions == null
|
||||
? conditions.All(c => c.StartsWith("!"))
|
||||
: conditions.All(
|
||||
c => scene.Conditions.Contains(c) ||
|
||||
(c.StartsWith("!") && !scene.Conditions.Contains(c)));
|
||||
var satisfied = scene.Conditions != null && conditions.All(c => scene.Conditions.Contains(c));
|
||||
|
||||
var text = anchor.Groups["text"].Value;
|
||||
var alts = RegexLib.ConditionalText.Match(text);
|
||||
|
@ -103,17 +98,18 @@
|
|||
RegexLib.EscapeChar.Replace(satisfied ? alts.Groups["true"].Value : alts.Groups["false"].Value,
|
||||
string.Empty);
|
||||
|
||||
// if there's no target or toggles, replace the whole anchor
|
||||
if (target == null && toggles == null)
|
||||
// if there's no target or toggles, or the replace text is an empty string, replace the whole anchor
|
||||
if (string.IsNullOrEmpty(replace) || (target == null && toggles == null))
|
||||
{
|
||||
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
|
||||
else
|
||||
{
|
||||
var parsedHref = RegexLib.Href.Match(anchor.Groups["href"].Value);
|
||||
scene.Description = scene.Description.Replace(anchor.Groups["anchor"].Value,
|
||||
string.Format("[{0}]({1}{2})", replace, anchor.Groups["target"].Value,
|
||||
anchor.Groups["toggles"].Value));
|
||||
string.Format("[{0}]({1}{2})", replace, parsedHref.Groups["target"].Value,
|
||||
parsedHref.Groups["toggles"].Value));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
namespace Ficdown.Parser
|
||||
{
|
||||
using System;
|
||||
using Engine;
|
||||
using Model.Story;
|
||||
|
||||
|
@ -22,7 +23,7 @@
|
|||
|
||||
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 story = BlockHandler.ParseBlocks(blocks);
|
||||
SceneLinker.ExpandScenes(story);
|
||||
|
|
Loading…
Reference in a new issue