Пример #1
0
        public async Task <IWikiContainer <IWikiArticle> > GetContainerAsync(IWikiArticle wikiArticle, Wikitext astRoot)
        {
            var wikiData = _wikiContentFactory.CreateWikiData(astRoot.ToPlainText(), ContentModel.WikiText);

            // Create the root of WikiComponent tree.
            var articleContainer = _wikiComponentFactory.CreateArticleContainer(wikiData, wikiArticle, astRoot, astRoot);

            var firstChild = astRoot.Lines.FirstNode;

            // Compose WikiComponent tree.
            var rootChildren = await _astTranslator.TranslateNodesAsync(firstChild);

            if (rootChildren.Any())
            {
                articleContainer.AddChildren(rootChildren);
            }
            else
            {
                _logger.LogWarning("AST translator returned empty list of article descendants.");
            }

            return(articleContainer);
        }
Пример #2
0
        // RULE: One component has one node or multiple nodes that are adjacent siblings, one node belongs to zero or one component.
        public bool ParseNode(Node startNode, out PatternMatchComponent?outMatchComponent)
        {
            PatternMatch?match = null;

            if (startNode is Template template)
            {
                match = RunPatternEnumeration(
                    _templateSpecifications.Select(
                        pattern => pattern.Expression(template)));
            }

            //else if (startNode is InlineNode inlineNode)
            //{
            //    match = RunPatternEnumeration(
            //        _inlinePatterns.Select(
            //            pattern => pattern(inlineNode)));
            //}
            //else
            //{
            //    match = RunPatternEnumeration(
            //        _patterns.Select(
            //            pattern => pattern(startNode)));
            //}

            if (match == null)
            {
                outMatchComponent = null;
                return(false);
            }

            // We have a match here, create component.

            if (match.WikiComponentType == WikiComponentType.Image)
            {
                // TODO: Must figure out lazy loading of data like images here.
                // Probably change the T IWikiContainer.Content member to something like T LoadContentAsync().
                // Then the container will load the content itself when asked to, which means it will need an instance of IArchive and IIdProvider.
                // So maybe create a service to wrap all that and pass it to the IWikiContainerFactory?

                throw new NotImplementedException();
            }

            var  rawDataSb  = new StringBuilder();
            Node exportNode = startNode;

            // TODO: This way, raw data of nested components will overlap. Is that OK? Shall there be a config for this?

            while (true)
            {
                rawDataSb.Append(exportNode.ToPlainText());

                if (exportNode == match.EndNode)
                {
                    break;
                }
                else
                {
                    // Assuming that there is a non-null node behind one that was not the end node.
                    exportNode = exportNode.NextNode;
                }
            }

            var rawData = _wikiContentFactory.CreateWikiData(rawDataSb.ToString(), ContentModel.WikiText);

            outMatchComponent = new PatternMatchComponent(match, _wikiComponentFactory.CreateComponent(rawData, match.WikiComponentType, startNode, match.EndNode));

            #region Log match

            var startNodeString    = startNode.ToString() ?? "";
            var startNodeSubstring = startNodeString.Substring(0, Math.Min(50, startNodeString.Length));
            _logger.LogDebug($"Found {match.WikiComponentType}.{Environment.NewLine}" +
                             $"Starts with: {startNodeSubstring}.{Environment.NewLine}" +
                             $"Has length of: {startNodeString.Length}.{Environment.NewLine}" +
                             $"Has hash: {startNodeString.GetHashCode()}");

            #endregion

            return(true);
        }