コード例 #1
0
        public TextNodesString Convert(IXmlNode node)
        {
            _parseStrings = new List <TextNodesString>();

            if (node.NodeType == IXmlNodeType.Text)
            {
                AddParseString(BuildParseString(new[] { node }));
            }
            else
            {
                FindParseStrings(node);
            }

            var result = new TextNodesString();
            var sb     = new StringBuilder();
            var cursor = 0;

            foreach (var textNodesString in _parseStrings)
            {
                if (cursor > 0)
                {
                    textNodesString.NodesInfo.ForEach(e => e.MoveBy(cursor));
                }

                sb.Append(textNodesString.Value);
                result.NodesInfo.AddRange(textNodesString.NodesInfo);
                cursor = sb.Length;
            }

            result.Value      = sb.ToString();
            result.IsReadonly = node.IsReadonly;
            return(result);
        }
コード例 #2
0
        private TextNodesString BuildParseString(IEnumerable <IXmlNode> nodes)
        {
            var result = new TextNodesString();
            var sb     = new StringBuilder();

            foreach (var node in nodes)
            {
                var textNode = node.GetTextNode();
                if (string.IsNullOrEmpty(textNode.InnerXml))
                {
                    continue;
                }

                var nodeText = textNode.InnerXml.Replace(HtmlTags.Nbsp, " ");
                result.NodesInfo.Add(new TextNodeEntry()
                {
                    Node        = textNode,
                    StartIndex  = sb.Length,
                    EndIndex    = sb.Length + nodeText.Length - 1,
                    CleanedText = nodeText
                });
                sb.Append(nodeText);
            }

            result.Value = sb.ToString();
            return(result);
        }
コード例 #3
0
        private void AddParseString(TextNodesString parseString)
        {
            if (string.IsNullOrEmpty(parseString.Value))
            {
                return;
            }

            _parseStrings.Add(parseString);
        }
コード例 #4
0
        private void ParseTextNodes(TextNodesString parseString)
        {
            var index      = 0;    // чтобы анализировать с первого символа, так как теперь поддерживаем ещё и такие ссылки, как "5:6 - ..."
            var verseEntry = stringParser.TryGetVerse(parseString.Value, index);

            var skipNodes = 0;

            while (verseEntry.VersePointerFound)
            {
                var verseWasRecognized = verseRecognitionService.TryRecognizeVerse(verseEntry, docParseContext);
                if (!verseWasRecognized && configurationManager.UseCommaDelimiter &&
                    verseEntry.EntryType <= VerseEntryType.ChapterVerse)
                {
                    verseEntry         = stringParser.TryGetVerse(parseString.Value, index, index, false);
                    verseWasRecognized = verseRecognitionService.TryRecognizeVerse(verseEntry, docParseContext);
                }

                if (verseWasRecognized)
                {
                    var verseNode = FindNodeAndMoveVerseTextInOneNodeIfNotReadonly(parseString, verseEntry, ref skipNodes);

                    if (!this.docParseContext.DocumentId.IsReadonly && !parseString.IsReadonly)
                    {
                        if (!NodeIsLink(verseNode.NodeEntry.Node.GetParentNode()))
                        {
                            InsertVerseLink(verseNode, verseEntry);
                        }
                        else
                        {
                            UpdateLinkNode(verseNode.NodeEntry.Node.GetParentNode(), verseEntry);
                        }
                    }

                    paragraphContextEditor.ParseResult.VerseEntries.Add(verseEntry);
                    paragraphContextEditor.SetLatestVerseEntry(verseEntry);
                }

                if (verseEntry.VersePointer.SubVerses.NotFoundVerses.Count > 0)
                {
                    paragraphContextEditor.ParseResult.NotFoundVerses.AddRange(verseEntry.VersePointer.SubVerses.NotFoundVerses);
                }

                var prevIndex = index;
                index = verseEntry.EndIndex + 1;
                if (index < parseString.Value.Length - 1)
                {
                    var leftBoundary = !verseWasRecognized && verseEntry.EntryType > VerseEntryType.ChapterVerse ? prevIndex : index;
                    verseEntry = stringParser.TryGetVerse(parseString.Value, index, leftBoundary, configurationManager.UseCommaDelimiter);
                }
                else
                {
                    break;
                }
            }
        }
コード例 #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="parseString"></param>
        /// <param name="verseEntryInfo"></param>
        /// <param name="skipNodes">Чтобы не проверять строку с начала</param>
        /// <returns></returns>
        private VerseInNodeEntry FindNodeAndMoveVerseTextInOneNodeIfNotReadonly(TextNodesString parseString, VerseEntry verseEntryInfo, ref int skipNodes)
        {
            var result = new VerseInNodeEntry();

            if (parseString.NodesInfo.Count > 1)
            {
                foreach (var nodeEntry in parseString.NodesInfo.Skip(skipNodes))
                {
                    if (result.NodeEntry == null)
                    {
                        if (nodeEntry.StartIndex <= verseEntryInfo.StartIndex && verseEntryInfo.StartIndex <= nodeEntry.EndIndex)
                        {
                            if (!nodeEntry.WasCleaned)
                            {
                                nodeEntry.Clean();  // то есть, если в этой ноде есть стих, тогда мы можем немного её почистить. Чтобы другие ноды не изменять.
                            }
                            result.NodeEntry  = nodeEntry;
                            result.StartIndex = verseEntryInfo.StartIndex - nodeEntry.StartIndex;
                            result.EndIndex   = (nodeEntry.EndIndex >= verseEntryInfo.EndIndex ? verseEntryInfo.EndIndex : nodeEntry.EndIndex) - nodeEntry.StartIndex;

                            if (this.docParseContext.DocumentId.IsReadonly || parseString.IsReadonly)
                            {
                                break;
                            }

                            if (nodeEntry.EndIndex >= verseEntryInfo.EndIndex)
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        if (!nodeEntry.WasCleaned)
                        {
                            nodeEntry.Clean();
                        }

                        var moveCharsCount = (verseEntryInfo.EndIndex > nodeEntry.EndIndex ? nodeEntry.EndIndex : verseEntryInfo.EndIndex) - nodeEntry.StartIndex + 1;
                        var verseTextPart  = nodeEntry.Node.InnerXml.Substring(0, moveCharsCount);
                        result.EndIndex                += moveCharsCount;
                        nodeEntry.StartIndex           += moveCharsCount; // здесь может быть ситуация, когда Startindex > EndIndex. Когда нода была из одного символа. Похоже, что это нормально. Так как мы больше нигде не используем эти ноды.
                        result.NodeEntry.Node.InnerXml += verseTextPart;
                        nodeEntry.Node.InnerXml         = nodeEntry.Node.InnerXml.Remove(0, moveCharsCount);

                        if (verseEntryInfo.EndIndex <= nodeEntry.EndIndex)
                        {
                            break;
                        }
                    }
                    skipNodes++;
                }
            }
            else
            {
                result.NodeEntry  = parseString.NodesInfo.First();
                result.StartIndex = verseEntryInfo.StartIndex;
                result.EndIndex   = verseEntryInfo.EndIndex;

                if (!result.NodeEntry.WasCleaned)
                {
                    result.NodeEntry.Clean();
                }
            }

            return(result);
        }