コード例 #1
0
        private IList <(string Name, string Book, string Location)> ExtractAffiliations(Node root)
        {
            string lastLink = null;
            var    list     = new List <(string, string, string)>();

            void PushLastLink(string b, string l)
            {
                if (lastLink != null)
                {
                    list.Add((lastLink, b, l));
                    lastLink = null;
                }
            }

            foreach (var node in root.EnumDescendants())
            {
                if (node is WikiLink link)
                {
                    PushLastLink(null, null);
                    lastLink = link.Target.ToString().Trim();
                }
                else if (node is Template template && MwParserUtility.NormalizeTitle(template.Name) == "R")
                {
                    if (lastLink != null)
                    {
                        var b = template.Arguments[1].ToString().Trim();
                        var l = template.Arguments[2]?.ToString().Trim();
                        PushLastLink(b, l);
                    }
                }
            }
            return(list);
        }
コード例 #2
0
 public static bool IsTemplateTitle(string title)
 {
     if (title == null)
     {
         throw new ArgumentNullException(nameof(title));
     }
     Debug.Assert(title == MwParserUtility.NormalizeTitle(title));
     return(title.StartsWith("Template:"));
 }
コード例 #3
0
        public SignatureHelp GetSignatureHelp(Position position, PageInfoStore store)
        {
            var  node     = TraceNode(position);
            Node lastNode = null;

            while (node != null)
            {
                switch (node)
                {
                case Template template:
                    var templateName = MwParserUtility.NormalizeTitle(template.Name);
                    if (string.IsNullOrEmpty(templateName))
                    {
                        return(null);
                    }
                    // i.e. redirect target
                    var redirectSource = store.TryGetTransclusionPageInfo(templateName);
                    if (redirectSource == null)
                    {
                        return(null);
                    }
                    var templateInfo = store.ResolveRedirectTarget(redirectSource);
                    if (templateInfo == null)
                    {
                        templateInfo   = redirectSource;
                        redirectSource = null;
                    }
                    var help = new SignatureHelp
                    {
                        Signatures      = new[] { templateInfo.ToSignatureInformation(redirectSource) },
                        ActiveSignature = 0,
                        ActiveParameter = -1,
                    };
                    if (lastNode is TemplateArgument arg)
                    {
                        // Magic Words are always positional, while it can fake "named arguments"
                        if (templateInfo.Type == PageType.MagicWord)
                        {
                            var pos = template.Arguments.IndexOf(arg);
                            help.ActiveParameter = pos;
                        }
                        else
                        {
                            var argName = arg.ArgumentName();
                            help.ActiveParameter = templateInfo.Arguments.IndexOf(p => p.Name == argName);
                        }
                    }
                    return(help);

                case WikiLink wikiLink:
                    return(null);
                }
                lastNode = node;
                node     = node.ParentNode;
            }
            return(null);
        }
コード例 #4
0
        public void TestTemplate1()
        {
            var root = ParseAndAssert(
                "{{disambig}}\nTest may refer to\n* Test and experiment.\n* The River Test.\n",
                "P[{{disambig}}\nTest may refer to]*[ Test and experiment.]*[ The River Test.]P[]");
            var dab = root.EnumDescendants().OfType <Template>()
                      .First(t => MwParserUtility.NormalizeTitle(t.Name) == "Disambig");

            Assert.Empty(dab.Arguments);
        }
コード例 #5
0
        private static string WikiTitleMd(Node node)
        {
            var text = node?.ToPlainText();

            if (string.IsNullOrEmpty(text))
            {
                return("…");
            }
            return(EscapeMd(MwParserUtility.NormalizeTitle(node)));
        }
コード例 #6
0
        GetCompletionItems(Position position, PageInfoStore store)
        {
            var  innermostNode      = TraceNode(position);
            var  innermostPlainText = innermostNode as PlainText;
            var  node     = innermostNode;
            Node lastNode = null;
            // ... when the innermostPlainText is also the first node of all parent nodes
            var isSimpleIdentifier         = innermostPlainText != null;
            var lastNodeIsSimpleIdentifier = isSimpleIdentifier;

            // Trace the node from innermost to outermost.
            while (node != null)
            {
                lastNodeIsSimpleIdentifier = isSimpleIdentifier;
                isSimpleIdentifier         = isSimpleIdentifier &&
                                             (node is PlainText || lastNode.PreviousNode == null);
                switch (node)
                {
                case Template template:
                    if (lastNodeIsSimpleIdentifier && lastNode == template.Name)
                    {
                        var enteredName = MwParserUtility.NormalizeTitle(GetTypedLhsText(innermostPlainText, position));
                        return(store.GetTransclusionCompletionItems(enteredName), true);
                    }
                    return(null, false);

                case TemplateArgument argument:
                    // Do not show auto-completion for obvious argument values.
                    if (lastNodeIsSimpleIdentifier && (
                            lastNode == argument.Name ||  // | abc$ = def
                            argument.Name == null && lastNode == argument.Value        // Anonymous argument, or unfinished argument name
                            ))
                    {
                        var template     = (Template)argument.ParentNode;
                        var templateInfo = store.TryGetTransclusionPageInfo(MwParserUtility.NormalizeTitle(template.Name));
                        return(templateInfo.Arguments
                               .Select(a => new CompletionItem(a.Name, CompletionItemKind.Property, a.Summary, a.Name + "=")),
                               false);
                    }
                    return(null, false);

                case WikiLink wikiLink:
                    if (lastNodeIsSimpleIdentifier && lastNode == wikiLink.Target)
                    {
                        var enteredName = MwParserUtility.NormalizeTitle(GetTypedLhsText(innermostPlainText, position));
                        return(store.GetWikiLinkCompletionItems(enteredName), true);
                    }
                    return(null, false);
                }
                lastNode = node;
                node     = node.ParentNode;
            }
            return(null, false);
        }
コード例 #7
0
        public void TemplateArgumentsTest2()
        {
            var root = ParseWikitext("{{\ttest_T  |A=1|B=2|  c\n=3}}");
            var t    = root.EnumDescendants().OfType <Template>().First();
            var arg2 = t.Arguments.ElementAt(2);

            Assert.Equal("Test T", MwParserUtility.NormalizeTitle(t.Name));
            Assert.Equal("c", MwParserUtility.NormalizeTemplateArgumentName(arg2.Name));
            t.Arguments["B"].Remove();
            Assert.Equal(2, t.Arguments.Count);
            Assert.Equal(arg2, t.Arguments.ElementAt(1));
        }
コード例 #8
0
        public void TestTemplate2()
        {
            var root = ParseAndAssert(
                "{{Translating|[[:en:Test]]|\ntpercent=20}}\n{{T|Translating|source|3=tpercent=percentage of completion}}",
                "P[{{Translating|P[[[:en:Test]]]|P[\ntpercent]=P[20]}}\n{{T|P[Translating]|P[source]|P[3]=P[tpercent=percentage of completion]}}]");
            var trans = root.EnumDescendants().OfType <Template>()
                        .First(t => MwParserUtility.NormalizeTitle(t.Name) == "Translating");

            Assert.Equal(2, trans.Arguments.Count);
            Assert.Equal("[[:en:Test]]", trans.Arguments[1].Value.ToString());
            Assert.Equal("20", trans.Arguments["  tpercent   "].Value.ToString());
        }
コード例 #9
0
        static async Task WorkAsync(IAsyncEnumerable <WikiPage> pages)
        {
            const string templateName = "WbClientLite/SiteLinks";
            var          parser       = new WikitextParser();
            var          counter      = 0;

            using (var ie = pages.GetEnumerator())
            {
                while (await ie.MoveNext())
                {
                    var page = ie.Current;
                    counter++;
                    Console.Write("{0}: {1} ", counter, page);
                    var root = parser.Parse(page.Content);
                    if (root.EnumDescendants().OfType <Template>().Any(t => MwParserUtility.NormalizeTitle(t.Name) == templateName))
                    {
                        Console.WriteLine("Skipped");
                        continue;
                    }
                    var langLinks = root.EnumDescendants().OfType <WikiLink>().Where(l =>
                    {
                        var wl = WikiClientLibrary.WikiLink.Parse(page.Site, l.Target.ToString());
                        return(wl.InterwikiPrefix != null);
                    }).ToList();
                    // Remove old language links.
                    foreach (var link in langLinks)
                    {
                        if (link.PreviousNode is PlainText pt1 && string.IsNullOrWhiteSpace(pt1.Content))
                        {
                            pt1.Remove();
                        }
                        if (link.NextNode is PlainText pt2 && string.IsNullOrWhiteSpace(pt2.Content))
                        {
                            pt2.Remove();
                        }
                        var parent = link.ParentNode;
                        link.Remove();
                        if (!parent.EnumChildren().Any())
                        {
                            parent.Remove();
                        }
                    }
                    // Insert new template.
                    root.Lines.Add(new Paragraph(new PlainText("\n"), new Template(new Run(new PlainText(templateName)))));
                    page.Content = root.ToString();
                    await page.UpdateContentAsync("使用CrystalPool提供的语言链接。", true, true);

                    Console.WriteLine("Done");
                }
            }
        }
コード例 #10
0
 /// <summary>
 /// Expands Abc as in {{Abc}} to Template:Abc.
 /// </summary>
 public static string ExpandTransclusionTitle(string title)
 {
     if (title == null)
     {
         throw new ArgumentNullException(nameof(title));
     }
     Debug.Assert(title == MwParserUtility.NormalizeTitle(title));
     if (title.StartsWith(":"))
     {
         return(title.Substring(1));
     }
     if (!title.Contains(':'))
     {
         return("Template:" + title);
     }
     // Something like {{Test:abcd}}, here we treat it as is with namespace name
     return(title);
 }
コード例 #11
0
        public static string EntityFromZhSiteLink(string link)
        {
            var query = CreateQuery(@"
                    SELECT ?item {
                        ?link   schema:isPartOf <https://warriors.huijiwiki.com/>;
                                schema:about ?item;
                                schema:name @title.
                    }");

            query.SetLiteral("title", MwParserUtility.NormalizeTitle(link), "zh");
            var result = ExecuteQuery(query);
            var uri    = ((IUriNode)result.FirstOrDefault()?.Value("item"))?.Uri;

            if (uri == null)
            {
                return(null);
            }
            return(StripEntityUri(uri));
        }
コード例 #12
0
        private void CheckNode(Template template, DiagnosticEmitter e)
        {
            if (((IWikitextParsingInfo)template).InferredClosingMark)
            {
                e.TransclusionNotClosed(template.ToRange(), MwParserUtility.NormalizeTitle(template.Name));
            }
            if (string.IsNullOrWhiteSpace(template.Name?.ToString()))
            {
                e.EmptyTransclusionTarget(template.ToRange());
            }
            var names = new HashSet <string>();

            foreach (var p in template.Arguments.EnumNameArgumentPairs())
            {
                if (!names.Add(p.Key))
                {
                    e.DuplicateTemplateArgument(p.Value.ToRange(), p.Key, MwParserUtility.NormalizeTitle(template.Name));
                }
            }
        }
コード例 #13
0
        public IEnumerable <string> FactsFromPage(WikiPage page)
        {
            var root       = wikiParser.Parse(page.Content);
            var infoboxCat = root.EnumDescendants().OfType <Template>()
                             .FirstOrDefault(t => MwParserUtility.NormalizeTitle(t.Name) == "Charcat");

            if (infoboxCat == null)
            {
                Console.WriteLine("No {{Charcat}} found.");
                yield return("% No {{Charcat}} found.");

                yield break;
            }
            var atom = AtomExpr(page.Title.Trim());

            yield return($"name({atom}, \"{StripDabTitle(page.Title)}\").");

            switch (EnWikiHelper.IsTom(root))
            {
            case true:
                yield return($"male({atom}).");

                break;

            case false:
                yield return($"female({atom}).");

                break;

            default:
                break;
            }
            var affie = infoboxCat.Arguments["affie"];

            if (affie != null)
            {
                foreach (var aff in affie.EnumDescendants().OfType <WikiLink>())
                {
                    yield return($"belongsto({atom}, {AtomExpr(aff.Target.ToPlainText().Trim())}).");
                }
            }
            var familyt = infoboxCat.Arguments["familyt"];
            var familyl = infoboxCat.Arguments["familyl"];

            if (familyt != null && familyl != null)
            {
                var familyDict = EnWikiHelper.ParseFamily(familyt.Value, familyl.Value);
                familyDict.TryGetValue("mother", out var mothers);
                familyDict.TryGetValue("father", out var fathers);
                var mother = mothers?.FirstOrDefault();
                var father = fathers?.FirstOrDefault();
                if (mother != null || father != null)
                {
                    Debug.Assert(mothers == null || mothers.Count <= 1);
                    Debug.Assert(fathers == null || fathers.Count <= 1);
                    yield return($"child({atom}, {AtomExpr(father ?? "x")}, {AtomExpr(mother ?? "x")}).");
                }
                else
                {
                    yield return("% No parent found.");
                }
            }
            else
            {
                Console.WriteLine("No familyt/familyl.");
                yield return("% No {{Charcat |familyl= |familyt= }} found.");
            }
            var apps = infoboxCat.Arguments["mentor"];

            if (apps != null)
            {
                foreach (var appr in apps.EnumDescendants().OfType <WikiLink>())
                {
                    yield return($"apprentice({atom}, {AtomExpr(appr.Target.ToPlainText().Trim())}).");
                }
            }
        }
コード例 #14
0
 public void NormalizeTitleTest1()
 {
     Assert.AreEqual("Test", MwParserUtility.NormalizeTitle(" \r\ntest\r\n "));
     Assert.AreEqual("Test test", MwParserUtility.NormalizeTitle(" \r\ntest test  _ "));
 }
コード例 #15
0
 // TODO Apply patch to MwParserFromScratch.
 public static string NormalizeTitle(Node title)
 {
     return(MwParserUtility.NormalizeTitle(title).Trim());
 }
コード例 #16
0
ファイル: Utility.cs プロジェクト: crystal-pool/Bootstrap
 public static IEnumerable <Template> TemplatesWithTitle(this IEnumerable <Node> nodes, string name)
 {
     return(nodes.OfType <Template>().Where(t => MwParserUtility.NormalizeTitle(t.Name) == name));
 }
コード例 #17
0
        /// <summary>
        /// Infers linked/transcluded pages information, and stores it into global store.
        /// </summary>
        public int InferTemplateInformation(PageInfoStore store)
        {
            if (store == null)
            {
                throw new ArgumentNullException(nameof(store));
            }
            // template, argument
            var dict = new Dictionary <string, Dictionary <string, TemplateArgumentInfo> >();

            foreach (var template in _Root.EnumDescendants().OfType <Template>())
            {
                if (template.IsMagicWord)
                {
                    continue;
                }
                var name = template.Name?.ToString();
                if (string.IsNullOrEmpty(name))
                {
                    continue;
                }
                name = MwParserUtility.NormalizeTitle(name);
                if (name.Contains('{') || name.Contains('}'))
                {
                    continue;
                }
                name = Utility.ExpandTransclusionTitle(name);
                // Start to infer it.
                if (!dict.TryGetValue(name, out var parameters))
                {
                    if (store.ContainsPageInfo(name))
                    {
                        continue;
                    }
                    parameters = new Dictionary <string, TemplateArgumentInfo>();
                    dict.Add(name, parameters);
                }
                foreach (var p in template.Arguments.EnumNameArgumentPairs())
                {
                    if (parameters.ContainsKey(p.Key))
                    {
                        continue;
                    }
                    // TODO: Insert documentation here.
                    parameters.Add(p.Key, new TemplateArgumentInfo(p.Key, null));
                }
            }
            foreach (var p in dict)
            {
                var    isTemplate = Utility.IsTemplateTitle(p.Key);
                string transclusionName;
                if (isTemplate)
                {
                    Debug.Assert(p.Key.StartsWith("Template:"));
                    transclusionName = p.Key.Substring(9);
                }
                else
                {
                    transclusionName = ":" + p.Key;
                }
                store.UpdatePageInfo(new PageInfo(p.Key, transclusionName, null, Prompts.InferredPageInfo,
                                                  p.Value.OrderBy(p1 => p1.Key, TemplateArgumentNameComparer.Default)
                                                  .Select(p1 => p1.Value).ToArray(), isTemplate ? PageType.Template : PageType.Page, true));
            }
            return(dict.Count);
        }