/// <summary> /// Will compile a new <see cref="IMacro"/> or return a previously cached <see cref="CompiledMacro"/>. /// </summary> /// <param name="macro">The macro to compile.</param> /// <returns>The compiled macro.</returns> public virtual CompiledMacro Compile(IMacro macro) { Guard.NotNull(macro, "macro"); Guard.NotNullOrEmpty(macro.Id, "macro", "The macro identifier must not be null or empty."); try { // for performance sake, // we'll initially use only a read lock compileLock.EnterReadLock(); CompiledMacro compiledMacro; if (compiledMacros.TryGetValue(macro.Id, out compiledMacro)) { return(compiledMacro); } } finally { compileLock.ExitReadLock(); } // this is assuming the compiled macro was not found // and will attempt to compile it. compileLock.EnterUpgradeableReadLock(); try { if (compiledMacros.ContainsKey(macro.Id)) { return(compiledMacros[macro.Id]); } compileLock.EnterWriteLock(); try { if (compiledMacros.ContainsKey(macro.Id)) { return(compiledMacros[macro.Id]); } Guard.NotNullOrEmpty(macro.Rules, "macro", "The macro rules must not be null or empty."); CompiledMacro compiledMacro = CompileMacro(macro); compiledMacros[macro.Id] = compiledMacro; return(compiledMacro); } finally { compileLock.ExitWriteLock(); } } finally { compileLock.ExitUpgradeableReadLock(); } }
private static IList<Scope> GetCapturedMatches(Match regexMatch, CompiledMacro macro, IList<Scope> capturedMatches, Regex regex) { for (int i = 0; i < regexMatch.Groups.Count; i++) { if (regex.GroupNameFromNumber(i) != i.ToString()) continue; Group regexGroup = regexMatch.Groups[i]; string capture = macro.Captures[i]; if (regexGroup.Captures.Count == 0 || String.IsNullOrEmpty(capture)) continue; foreach (Capture regexCapture in regexGroup.Captures) AppendCapturedMatchesForRegexCapture(regexCapture, capture, capturedMatches); } return capturedMatches; }
private static void Parse(string wikiContent, IMacro macro, CompiledMacro compiledMacro, IScopeAugmenter augmenter, Action<IList<Scope>> parseHandler) { Match regexMatch = compiledMacro.Regex.Match(wikiContent); if (!regexMatch.Success) return; IList<Scope> capturedScopes = new List<Scope>(); while (regexMatch.Success) { string matchedContent = wikiContent.Substring(regexMatch.Index, regexMatch.Length); if (!string.IsNullOrEmpty(matchedContent)) capturedScopes = GetCapturedMatches(regexMatch, compiledMacro, capturedScopes, compiledMacro.Regex); regexMatch = regexMatch.NextMatch(); } if (augmenter != null && capturedScopes.Count > 0) capturedScopes = augmenter.Augment(macro, capturedScopes, wikiContent); if (capturedScopes.Count > 0) parseHandler(capturedScopes); }