/// <summary> /// Renders a raw link element. /// </summary> /// <param name="element"> The parsed inline element to render. </param> /// <param name="context"> Persistent state. </param> protected override void RenderHyperlink(HyperlinkInline element, IRenderContext context) { if (!(context is InlineRenderContext localContext)) { throw new RenderContextIncorrectException(); } var link = new Hyperlink(); LinkRegister.RegisterNewHyperLink(link, element.Url); var brush = localContext.Foreground; if (LinkForeground != null && !localContext.OverrideForeground) { brush = LinkForeground; } Run linkText = new Run { Text = CollapseWhitespace(context, element.Text), Foreground = brush }; link.Inlines.Add(linkText); localContext.InlineCollection.Add(link); }
/// <summary> /// Renders a raw link element. /// </summary> /// <param name="element"> The parsed inline element to render. </param> /// <param name="context"> Persistent state. </param> protected override void RenderHyperlink(HyperlinkInline element, IRenderContext context) { var localContext = context as InlineRenderContext; if (localContext == null) { throw new RenderContextIncorrectException(); } var link = new Hyperlink(); // Register the link LinkRegister.RegisterNewHyperLink(link, element.Url); var brush = localContext.Foreground; if (LinkForeground != null && !localContext.OverrideForeground) { brush = LinkForeground; } // Make a text block for the link Run linkText = new Run { Text = CollapseWhitespace(context, element.Text), Foreground = brush }; link.Inlines.Add(linkText); // Add it to the current inlines localContext.InlineCollection.Add(link); }
static Common() { BoldTextInline.AddTripChars(_triggerList); ItalicTextInline.AddTripChars(_triggerList); MarkdownLinkInline.AddTripChars(_triggerList); HyperlinkInline.AddTripChars(_triggerList); StrikethroughTextInline.AddTripChars(_triggerList); SuperscriptTextInline.AddTripChars(_triggerList); CodeInline.AddTripChars(_triggerList); // Create an array of characters to search against using IndexOfAny. _tripCharacters = _triggerList.Select(trigger => trigger.FirstChar).Distinct().ToArray(); }
/// <summary> /// Renders a raw link element. /// </summary> /// <param name="inlineCollection"> The list to add to. </param> /// <param name="element"> The parsed inline element to render. </param> /// <param name="parent"> The container element. </param> /// <param name="context"> Persistent state. </param> private void RenderHyperlink(InlineCollection inlineCollection, HyperlinkInline element, TextElement parent, RenderContext context) { var link = new Hyperlink(); // Register the link this.linkRegister.RegisterNewHyperLink(link, element.Url); // Make a text block for the link Run linkText = new Run(); linkText.Text = CollapseWhitespace(context, element.Text); link.Inlines.Add(linkText); // Add it to the current inlines inlineCollection.Add(link); }
static Common() { BoldItalicTextInline.AddTripChars(_triggerList); UnderlineTextInline.AddTripChars(_triggerList); BoldTextInline.AddTripChars(_triggerList); ItalicTextInline.AddTripChars(_triggerList); MarkdownLinkInline.AddTripChars(_triggerList); HyperlinkInline.AddTripChars(_triggerList); StrikethroughTextInline.AddTripChars(_triggerList); CodeInline.AddTripChars(_triggerList); ImageInline.AddTripChars(_triggerList); EmojiInline.AddTripChars(_triggerList); LinkAnchorInline.AddTripChars(_triggerList); DiscordInline.AddTripChars(_triggerList); SpoilerTextInline.AddTripChars(_triggerList); // Create an array of characters to search against using IndexOfAny. _tripCharacters = _triggerList.Select(trigger => trigger.FirstChar).Distinct().ToArray(); }
/// <summary> /// Finds the next inline element by matching trip chars and verifying the match. /// </summary> /// <param name="markdown"> The markdown text to parse. </param> /// <param name="start"> The position to start parsing. </param> /// <param name="end"> The position to stop parsing. </param> /// <param name="ignoreLinks"> Indicates whether to parse links. </param> /// <returns>Returns the next element</returns> private static InlineParseResult FindNextInlineElement(string markdown, int start, int end, bool ignoreLinks) { // Search for the next inline sequence. for (int pos = start; pos < end; pos++) { // IndexOfAny should be the fastest way to skip characters we don't care about. pos = markdown.IndexOfAny(_tripCharacters, pos, end - pos); if (pos < 0) { break; } // Find the trigger(s) that matched. char currentChar = markdown[pos]; foreach (InlineTripCharHelper currentTripChar in _triggerList) { // Check if our current char matches the suffix char. if (currentChar == currentTripChar.FirstChar) { // Don't match if the previous character was a backslash. if (pos > start && markdown[pos - 1] == '\\') { continue; } // If we are here we have a possible match. Call into the inline class to verify. InlineParseResult parseResult = null; switch (currentTripChar.Method) { case InlineParseMethod.BoldItalic: parseResult = BoldItalicTextInline.Parse(markdown, pos, end); break; case InlineParseMethod.Comment: parseResult = CommentInline.Parse(markdown, pos, end); break; case InlineParseMethod.LinkReference: parseResult = LinkAnchorInline.Parse(markdown, pos, end); break; case InlineParseMethod.Bold: parseResult = BoldTextInline.Parse(markdown, pos, end); break; case InlineParseMethod.Italic: parseResult = ItalicTextInline.Parse(markdown, pos, end); break; case InlineParseMethod.MarkdownLink: if (!ignoreLinks) { parseResult = MarkdownLinkInline.Parse(markdown, pos, end); } break; case InlineParseMethod.AngleBracketLink: if (!ignoreLinks) { parseResult = HyperlinkInline.ParseAngleBracketLink(markdown, pos, end); } break; case InlineParseMethod.Url: if (!ignoreLinks) { parseResult = HyperlinkInline.ParseUrl(markdown, pos, end); } break; case InlineParseMethod.RedditLink: if (!ignoreLinks) { parseResult = HyperlinkInline.ParseRedditLink(markdown, pos, end); } break; case InlineParseMethod.PartialLink: if (!ignoreLinks) { parseResult = HyperlinkInline.ParsePartialLink(markdown, pos, end); } break; case InlineParseMethod.Email: if (!ignoreLinks) { parseResult = HyperlinkInline.ParseEmailAddress(markdown, start, pos, end); } break; case InlineParseMethod.Strikethrough: parseResult = StrikethroughTextInline.Parse(markdown, pos, end); break; case InlineParseMethod.Superscript: parseResult = SuperscriptTextInline.Parse(markdown, pos, end); break; case InlineParseMethod.Subscript: parseResult = SubscriptTextInline.Parse(markdown, pos, end); break; case InlineParseMethod.Code: parseResult = CodeInline.Parse(markdown, pos, end); break; case InlineParseMethod.Image: parseResult = ImageInline.Parse(markdown, pos, end); break; case InlineParseMethod.Emoji: parseResult = EmojiInline.Parse(markdown, pos, end); break; } if (parseResult != null) { return(parseResult); } } } } // If we didn't find any elements we have a normal text block. // Let us consume the entire range. return(new InlineParseResult(TextRunInline.Parse(markdown, start, end), start, end)); }
/// <summary> /// Renders a raw link element. /// </summary> /// <param name="element"> The parsed inline element to render. </param> /// <param name="context"> Persistent state. </param> protected override void RenderHyperlink(HyperlinkInline element, IRenderContext context) { var localContext = context as InlineRenderContext; if (localContext == null) { throw new RenderContextIncorrectException(); } if (element.LinkType == HyperlinkType.DiscordUserMention || element.LinkType == HyperlinkType.DiscordChannelMention || element.LinkType == HyperlinkType.DiscordRoleMention || element.LinkType == HyperlinkType.DiscordNickMention || element.LinkType == HyperlinkType.QuarrelColor) { bool _halfopacity = false; var link = new HyperlinkButton(); var content = element.Text; bool enabled = true; SolidColorBrush foreground = (SolidColorBrush)Application.Current.Resources["Blurple"]; try { if (element.LinkType == HyperlinkType.DiscordUserMention || element.LinkType == HyperlinkType.DiscordNickMention) { string mentionid = element.Text.Remove(0, (element.LinkType == HyperlinkType.DiscordNickMention ? 2 : 1)); if (Document.Users != null) { Document.Users.TryGetValue(mentionid, out var user); if (!string.IsNullOrEmpty(user.Name)) { link.Tag = mentionid; content = _halfopacity ? user.Name : "@" + user.Name; foreground = IntToColor(user.Colour); /*if (GuildsService.CurrentGuild.Model.Name != "DM") * { * CurrentUsersService.Users.TryGetValue(mentionid, out var member); * if (!string.IsNullOrWhiteSpace(member?.DisplayName)) * { * if (_halfopacity) content = member.DisplayName; * else content = "@" + member.DisplayName; * * foreground = IntToColor(member.TopRole.Color); * } * }*/ } } } else if (element.LinkType == HyperlinkType.DiscordChannelMention) { var key = element.Text.Remove(0, 1); if (Document.Channels != null) { Document.Channels.TryGetValue(key, out var value); content = "#" + value; enabled = true; link.Tag = value; } else { content = "#deleted-channel"; enabled = false; } } else if (element.LinkType == HyperlinkType.DiscordRoleMention) { if (Document.Roles != null && Document.Roles.TryGetValue(element.Text.Remove(0, 2), out var role)) { if (_halfopacity) { content = role.Name; } else { content = "@" + role.Name; } foreground = IntToColor(role.Colour); } else { enabled = false; content = "@deleted-role"; } } else if (element.LinkType == HyperlinkType.QuarrelColor) { string intcolor = element.Text.Replace("@$QUARREL-color", ""); try { var color = IntToColor(Int32.Parse(intcolor)); localContext.InlineCollection.Add(new InlineUIContainer { Child = new Ellipse() { Height = FontSize, Width = FontSize, Fill = color, Margin = new Thickness(0, 0, 2, -2) } }); localContext.InlineCollection.Add(new Run { FontWeight = FontWeights.SemiBold, //Foreground = BoldForeground, Text = color.Color.ToString() }); return; } catch { } } } catch (Exception) { content = "<Invalid Mention>"; } link.Content = CollapseWhitespace(context, content); link.Foreground = foreground; link.FontSize = FontSize; if (_halfopacity) { link.Style = (Style)Application.Current.Resources["DiscordMentionHyperlinkBold"]; } else { link.Style = (Style)Application.Current.Resources["DiscordMentionHyperlink"]; } link.IsEnabled = enabled; LinkRegister.RegisterNewHyperLink(link, element.Url); InlineUIContainer linkContainer = new InlineUIContainer { Child = link }; localContext.InlineCollection.Add(linkContainer); } else { var link = new Hyperlink(); // Register the link LinkRegister.RegisterNewHyperLink(link, element.Url); var brush = localContext.Foreground; if (LinkForeground != null && !localContext.OverrideForeground) { brush = LinkForeground; } // Make a text block for the link Run linkText = new Run { Text = CollapseWhitespace(context, element.Text), Foreground = brush }; link.Inlines.Add(linkText); // Add it to the current inlines localContext.InlineCollection.Add(link); } }
/// <summary> /// Renders a raw link element. /// </summary> /// <param name="element"> The parsed inline element to render. </param> /// <param name="context"> Persistent state. </param> protected abstract void RenderHyperlink(HyperlinkInline element, IRenderContext context);
protected override void RenderHyperlink(HyperlinkInline element, IRenderContext context) { RenderLink(element.Text, element.Url, context); }
protected override void RenderHyperlink(HyperlinkInline element, IRenderContext context) { }
/// <summary> /// Renders a raw link element. /// </summary> /// <param name="inlineCollection"> The list to add to. </param> /// <param name="element"> The parsed inline element to render. </param> /// <param name="context"> Persistent state. </param> private void RenderHyperlink(InlineCollection inlineCollection, HyperlinkInline element, RenderContext context) { var link = new HyperlinkButton(); if (element.LinkType == HyperlinkType.DiscordUserMention || element.LinkType == HyperlinkType.DiscordChannelMention || element.LinkType == HyperlinkType.DiscordRoleMention || element.LinkType == HyperlinkType.DiscordNickMention || element.LinkType == HyperlinkType.QuarrelColor) { var content = element.Text; bool enabled = true; SolidColorBrush foreground = (SolidColorBrush)SimpleIoc.Default.GetInstance <IResourceService>().GetResource("Blurple"); try { if (element.LinkType == HyperlinkType.DiscordUserMention || element.LinkType == HyperlinkType.DiscordNickMention) { string mentionid = element.Text.Remove(0, element.LinkType == HyperlinkType.DiscordNickMention ? 2 : 1); if (_users != null) { foreach (var user in _users) { if (user.Id == mentionid) { link.Tag = user; if (_halfopacity) { content = user.Username; } else { content = "@" + user.Username; } if (_guildsService.CurrentGuild.Model.Name != "DM") { var member = _guildsService.GetGuildMember(mentionid, _guildsService.CurrentGuild.Model.Id); if (!string.IsNullOrWhiteSpace(member?.DisplayName)) { if (_halfopacity) { content = member.DisplayName; } else { content = "@" + member.DisplayName; } foreground = ColorExtensions.IntToBrush(member.TopRole.Color); } } break; } } } } else if (element.LinkType == HyperlinkType.DiscordChannelMention) { var key = element.Text.Remove(0, 1); BindableChannel value = _channelsService.GetChannel(key); content = "#" + (value?.Model?.Name ?? "deleted-channel"); enabled = value != null; link.Tag = value; } else if (element.LinkType == HyperlinkType.DiscordRoleMention) { var role = _guildsService.CurrentGuild.Model.Roles.FirstOrDefault(x => x.Id == element.Text.Remove(0, 2)); if (role != null) { if (_halfopacity) { content = role.Name; } else { content = "@" + role.Name; } foreground = ColorExtensions.IntToBrush(role.Color); } else { enabled = false; content = "@deleted-role"; } } else if (element.LinkType == HyperlinkType.QuarrelColor) { string intcolor = element.Text.Replace("@$QUARREL-color", string.Empty); try { var color = ColorExtensions.IntToBrush(int.Parse(intcolor)); inlineCollection.Add(new InlineUIContainer { Child = new Ellipse() { Height = FontSize, Width = FontSize, Fill = color, Margin = new Thickness(0, 0, 2, -2), }, }); inlineCollection.Add(new Run { FontWeight = FontWeights.SemiBold, Foreground = BoldForeground, Text = color.Color.ToString(), }); return; } catch { } } } catch (Exception) { content = "<Invalid Mention>"; } link.Content = CollapseWhitespace(context, content); link.Foreground = foreground; link.FontSize = FontSize; if (_halfopacity) { link.Style = (Style)Application.Current.Resources["DiscordMentionHyperlinkBold"]; } else { link.Style = (Style)Application.Current.Resources["DiscordMentionHyperlink"]; } link.IsEnabled = enabled; _linkRegister.RegisterNewHyperLink(link, element.Url); InlineUIContainer linkContainer = new InlineUIContainer { Child = link }; inlineCollection.Add(linkContainer); } else { var hLink = new Hyperlink(); _linkRegister.RegisterNewHyperLink(hLink, element.Url); Run linkText = new Run { Text = CollapseWhitespace(context, element.Text), Foreground = LinkForeground ?? context.Foreground, }; hLink.Inlines.Add(linkText); // Add it to the current inlines inlineCollection.Add(hLink); } }