IStoryThread EnchantIntoLink(Func <IStoryThread> linkAction) { HarloweEnchantment enchantment = _activeEnchantments.Peek(); foreach (StoryOutput affected in enchantment.Affected) { if (!(affected is StoryText)) { continue; } //yield return affected; if (enchantment.ReferenceType == HarloweEnchantReferenceType.Text) { MatchCollection matches = enchantment.Occurences.Matches(affected.Text); int startCharIndex = 0; foreach (Match m in matches) { // Return text till here if (m.Index > startCharIndex) { yield return(new StoryText(affected.Text.Substring(startCharIndex, m.Index - startCharIndex))); } // Return text of this match yield return(new StoryLink(m.Value, linkAction)); startCharIndex = m.Index + m.Length; } // Return remaining text if (startCharIndex < affected.Text.Length) { yield return(new StoryText(affected.Text.Substring(startCharIndex))); } } else { // See commented out EnchantIntoLinkUndo //yield return new TwineLink(affected.Text, () => EnchantIntoLinkUndo(linkAction)); yield return(new StoryLink(affected.Text, linkAction)); } } }
protected EmbedFragment enchant(StoryVar reference, HarloweEnchantCommand command, Func <IStoryThread> fragment) { bool isHookRef = reference.Value is HarloweHookRef; string str = isHookRef ? ((HarloweHookRef)reference.Value).HookName : reference.ToString(); List <HarloweEnchantment> enchantments = new List <HarloweEnchantment>(); HarloweEnchantment lastHookEnchantment = null; for (int i = 0; i < this.Output.Count; i++) { StoryOutput output = this.Output[i]; if (isHookRef) { // Check if matching hook found in the current group, otherwise skip if (!(output is StyleGroup)) { continue; } var group = output as StyleGroup; if (group.Style.Get <string>(HarloweStyleSettings.Hook) != str) { continue; } // Matching hook was found, but enchantment metadata is not up to date if (lastHookEnchantment == null || lastHookEnchantment.HookGroup != group) { lastHookEnchantment = new HarloweEnchantment() { ReferenceType = HarloweEnchantReferenceType.Hook, Command = command, HookGroup = group, Affected = new List <StoryOutput>() }; enchantments.Add(lastHookEnchantment); } // Add all outputs associated with this group i++; while (i < this.Output.Count && this.Output[i].BelongsToStyleGroup(group)) { lastHookEnchantment.Affected.Add(this.Output[i]); i++; } } else if (output is StoryText) { var occurences = new Regex(Regex.Escape(str)); if (occurences.IsMatch(output.Text)) { enchantments.Add(new HarloweEnchantment { ReferenceType = HarloweEnchantReferenceType.Text, Command = command, Affected = new List <StoryOutput>() { output }, Text = str, Occurences = occurences }); } } } return(new EmbedFragment(() => EnchantExecute(enchantments, fragment))); }