/// <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();
            }
        }
Exemple #2
0
        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;
        }
Exemple #3
0
        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);
        }