Example #1
0
        /// <summary>
        /// PARAGRAPH
        /// </summary>
        /// <remarks>The parsing operation will always succeed.</remarks>
        private LineNode ParseCompactParagraph(LineNode lastNode)
        {
            var mergeTo = lastNode as Paragraph;

            if (mergeTo != null && !mergeTo.Compact)
            {
                mergeTo = null;
            }
            // Create a new paragraph, or merge the new line to the last unclosed paragraph.
            ParseStart();
            if (mergeTo != null)
            {
                // This won't throw exception. See (A) in ParseLineEnd.
                var paraTail = (PlainText)mergeTo.Inlines.LastNode;
                paraTail.Content += "\n";
                IWikitextLineInfo paraTailSpan = paraTail;
                Debug.Assert(((IWikitextLineInfo)mergeTo).EndLinePosition == paraTailSpan.EndLinePosition);
                paraTail.ExtendLineInfo(paraTailSpan.EndLineNumber + 1, 0);
                mergeTo.ExtendLineInfo(paraTailSpan.EndLineNumber + 1, 0);
            }
            var node = mergeTo ?? new Paragraph();

            // Allows an empty paragraph/line.
            ParseRun(RunParsingMode.Run, node, false);
            if (mergeTo != null)
            {
                // Amend the line position
                lastNode.ExtendLineInfo(lineNumber, linePosition);
                return(ParseSuccessful(EMPTY_LINE_NODE, false));
            }
            return(ParseSuccessful(node));
        }
Example #2
0
 private Node TraceNode(Node root, Position position)
 {
     foreach (var node in root.EnumChildren())
     {
         IWikitextLineInfo span = node;
         Debug.Assert(span.HasLineInfo);
         if (span.StartLineNumber > position.Line)
         {
             continue;
         }
         if (span.EndLineNumber < position.Line)
         {
             continue;
         }
         if (span.StartLineNumber == position.Line && span.StartLinePosition > position.Character)
         {
             continue;
         }
         if (span.EndLineNumber == position.Line && span.EndLinePosition < position.Character)
         {
             continue;
         }
         return(TraceNode(node, position));
     }
     return(root);
 }
Example #3
0
        public Hover GetHover(Position position)
        {
            var node = TraceNode(position);

            if (node == null)
            {
                return(null);
            }
            Node prevNode  = null;
            var  nodeTrace = new List <string>();
            IWikitextLineInfo focusNode = null;

            while (node != null)
            {
                switch (node)
                {
                case Template _:
                    if (prevNode is TemplateArgument)
                    {
                        break;          // We will show template name in NodeToMd(TemplateArgument)
                    }
                    goto SHOW_NODE;

                case TagNode _:
                    if (prevNode is TagAttribute)
                    {
                        break;          // We will show template name in NodeToMd(TagAttribute)
                    }
                    goto SHOW_NODE;

                case TemplateArgument _:
                case ArgumentReference _:
                case WikiLink _:
                case ExternalLink _:
                case FormatSwitch _:
                case TagAttribute _:
                case Comment _:
SHOW_NODE:
                    if (focusNode == null)
                    {
                        focusNode = node;
                    }
                    nodeTrace.Add(Utility.NodeToMd(node));
                    break;
                }
                prevNode = node;
                node     = node.ParentNode;
            }
            if (focusNode == null)
            {
                return(null);
            }
            Debug.Assert(focusNode.HasLineInfo);
            nodeTrace.Reverse();
            return(new Hover(string.Join(" → ", nodeTrace), focusNode.ToRange()));
        }
Example #4
0
 public static Range ToRange(this IWikitextLineInfo thisNode)
 {
     if (thisNode == null)
     {
         throw new ArgumentNullException(nameof(thisNode));
     }
     Debug.Assert(thisNode.HasLineInfo);
     return(new Range(thisNode.StartLineNumber, thisNode.StartLinePosition,
                      thisNode.EndLineNumber, thisNode.EndLinePosition));
 }
Example #5
0
        /// <summary>
        /// Gets the text to the left-hand-side of the cart. Used for auto-completion.
        /// </summary>
        private string GetTypedLhsText(PlainText node, Position caretPosition)
        {
            IWikitextLineInfo li = node;

            Debug.Assert(li.HasLineInfo);
            var startPos = new Position(li.StartLineNumber, li.StartLinePosition);

            Debug.Assert(startPos <= caretPosition);
            Debug.Assert(new Position(li.EndLineNumber, li.EndLinePosition) >= caretPosition);
            return(TextDocument.GetRange(new Range(startPos, caretPosition)));
        }
        public void EnumDescendantsTest()
        {
            // I'm lazy. That's all.
            var root = ParseAndAssert(
                "{{Translating|[[:en:Test]]|tpercent=20}}\n[[]]<div style=\"background: red\">{{T|Translating|source|3=tpercent=percentage of completion}}</div>",
                "P[{{Translating|P[[[:en:Test]]]|P[tpercent]=P[20]}}\n$[$[$]$]<div style=\"background: red\">P[{{T|P[Translating]|P[source]|P[3]=P[tpercent=percentage of completion]}}]</div>]");

            Trace.WriteLine("Descendants Dump:");
            foreach (var node in root.EnumDescendants())
            {
                var si = (IWikitextLineInfo)node;
                Assert.True(si.HasLineInfo);
                Trace.WriteLine(
                    $"{node.GetType().Name}\t({si.StartLineNumber},{si.StartLinePosition})-({si.EndLineNumber},{si.EndLinePosition})\t[|{node}|]");
                if (node is IInlineContainer container)
                {
                    IWikitextLineInfo lastChild = null;
                    foreach (IWikitextLineInfo child in container.Inlines)
                    {
                        if (lastChild != null)
                        {
                            if (lastChild.EndLineNumber == child.StartLineNumber)
                            {
                                Assert.True(lastChild.EndLinePosition == child.StartLinePosition, "LineInfo of Inline sequence is not consequent.");
                            }
                            else
                            {
                                Assert.True(child.StartLinePosition == 0, "LineInfo of Inline sequence is not consequent.");
                            }
                        }
                        lastChild = child;
                    }
                }
            }
            var nn = root.Lines.FirstNode.NextNode;

            root.Lines.FirstNode.Remove();
            Assert.Equal(root.Lines.FirstNode, nn);
        }