private void Parse(Span span) { var context = new ParseContext(span); while (true) { Token token = LA(1); Consume(); if (token.TokenType == BBCodeLexer.TokenStartTag) { ParseTag(token.Value, true, context); } else if (token.TokenType == BBCodeLexer.TokenEndTag) { ParseTag(token.Value, false, context); } else if (token.TokenType == BBCodeLexer.TokenText) { var parent = span; Uri uri; string parameter = null; string targetName = null; // parse uri value for optional parameter and/or target, eg [url=cmd://foo|parameter|target] if (NavigationHelper.TryParseUriWithParameters(context.NavigateUri, out uri, out parameter, out targetName)) { var link = new Hyperlink(); // assign ICommand instance if available, otherwise set NavigateUri ICommand command; if (this.Commands != null && this.Commands.TryGetValue(uri, out command)) { link.Command = command; link.CommandParameter = parameter; if (targetName != null) { link.CommandTarget = this.source.FindName(targetName) as IInputElement; } } else { link.NavigateUri = uri; link.TargetName = parameter; } parent = link; span.Inlines.Add(parent); } var run = context.CreateRun(token.Value); parent.Inlines.Add(run); } else if (token.TokenType == BBCodeLexer.TokenLineBreak) { span.Inlines.Add(new LineBreak()); } else if (token.TokenType == BBCodeLexer.TokenAttribute) { throw new ParseException(Resources.UnexpectedToken); } else if (token.TokenType == BBCodeLexer.TokenEnd) { break; } else { throw new ParseException(Resources.UnknownTokenType); } } }
private void Parse(Span span) { var context = new ParseContext(span); while (true) { var token = La(1); Consume(); switch (token.TokenType) { case BbCodeLexer.TokenStartTag: ParseTag(token.Value, true, context); break; case BbCodeLexer.TokenEndTag: ParseTag(token.Value, false, context); break; case BbCodeLexer.TokenText: var parent = span; { Uri uri; string parameter; string targetName; // parse uri value for optional parameter and/or target, eg [url=cmd://foo|parameter|target] if (NavigationHelper.TryParseUriWithParameters(context.NavigateUri, out uri, out parameter, out targetName)) { var link = new Hyperlink(); if (context.IconGeometry != null) { link.TextDecorations.Clear(); } // assign ICommand instance if available, otherwise set NavigateUri ICommand command; if (Commands != null && Commands.TryGetValue(uri, out command)) { link.Command = command; link.CommandParameter = parameter; if (targetName != null) { link.CommandTarget = _source?.FindName(targetName) as IInputElement; } } else { link.NavigateUri = uri; link.TargetName = parameter; } parent = link; span.Inlines.Add(parent); } } if (context.IconGeometry != null) { var icon = new Path { Stretch = Stretch.Uniform, Data = context.IconGeometry }; icon.SetBinding(Shape.FillProperty, new Binding { Path = new PropertyPath("(TextBlock.Foreground)"), RelativeSource = new RelativeSource(RelativeSourceMode.Self), }); Logging.Debug(token.Value); var border = new Border { Background = new SolidColorBrush(Colors.Transparent), Child = icon, ToolTip = new ToolTip { Content = new TextBlock { Text = token.Value } } }; border.SetBinding(FrameworkElement.HeightProperty, new Binding { Path = new PropertyPath("(TextBlock.FontSize)"), RelativeSource = new RelativeSource(RelativeSourceMode.Self), Converter = new MultiplyConverter(), ConverterParameter = 0.7 }); border.SetBinding(FrameworkElement.WidthProperty, new Binding { Path = new PropertyPath(nameof(Border.Height)), RelativeSource = new RelativeSource(RelativeSourceMode.Self) }); parent.Inlines.Add(new InlineUIContainer { Child = border }); continue; } { string uri; double maxSize; bool expand, toolTip; FileCache cache; if (context.ImageUri?.StartsWith(@"emoji://") == true) { maxSize = 0; expand = false; toolTip = false; var provider = BbCodeBlock.OptionEmojiProvider; if (provider == null) { uri = null; cache = null; } else { var emoji = context.ImageUri.Substring(8); uri = string.Format(provider, emoji); cache = BbCodeBlock.OptionEmojiCacheDirectory == null ? null : _emojiCache ?? (_emojiCache = new FileCache(BbCodeBlock.OptionEmojiCacheDirectory)); } } else { toolTip = true; Uri temporary; string parameter; string targetName; if (NavigationHelper.TryParseUriWithParameters(context.ImageUri, out temporary, out parameter, out targetName)) { uri = temporary.OriginalString; if (double.TryParse(parameter, out maxSize)) { expand = true; } else { maxSize = double.NaN; expand = false; } cache = BbCodeBlock.OptionImageCacheDirectory == null ? null : _imageCache ?? (_imageCache = new FileCache(BbCodeBlock.OptionImageCacheDirectory)); } else { uri = null; maxSize = double.NaN; expand = false; cache = null; } } if (uri != null) { FrameworkElement image = new Image(cache) { ImageUrl = uri }; if (toolTip) { image.ToolTip = new ToolTip { Content = new TextBlock { Text = token.Value } }; } if (double.IsNaN(maxSize)) { RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.LowQuality); } else { if (Equals(maxSize, 0d)) { image.SetBinding(FrameworkElement.MaxHeightProperty, new Binding { Path = new PropertyPath(nameof(TextBlock.FontSize)), RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(TextBlock), 1), Converter = new MultiplyConverter(), }); image.Margin = new Thickness(1, -1, 1, -1); } else { image.MaxWidth = maxSize; image.MaxHeight = maxSize; } RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.HighQuality); } if (expand) { image.Cursor = Cursors.Hand; image.MouseDown += (sender, args) => { args.Handled = true; BbCodeBlock.OnImageClicked(new BbCodeImageEventArgs(new Uri(uri, UriKind.RelativeOrAbsolute))); }; } var container = new InlineUIContainer { Child = image }; parent.Inlines.Add(container); continue; } } var run = context.CreateRun(token.Value); parent.Inlines.Add(run); break; case BbCodeLexer.TokenLineBreak: span.Inlines.Add(new LineBreak()); break; case BbCodeLexer.TokenAttribute: throw new ParseException(UiStrings.UnexpectedToken); case Lexer.TokenEnd: return; default: throw new ParseException(UiStrings.UnknownTokenType); } } }
private void Parse(Span span) { var context = new ParseContext(span); while (true) { Token token = LA(1); Consume(); if (token.TokenType == BBCodeLexer.TokenStartTag) { ParseTag(token.Value, true, context); } else if (token.TokenType == BBCodeLexer.TokenEndTag) { ParseTag(token.Value, false, context); } else if (token.TokenType == BBCodeLexer.TokenText) { var parent = span; if (context.NavigateUri != null) { // parse uri value for optional parameter and/or target, eg [url=cmd://foo|parameter|target] string uriStr = context.NavigateUri; string parameter = null; string targetName = null; var parts = uriStr.Split(new char[] { '|' }, 3); if (parts.Length == 3) { uriStr = parts[0]; parameter = Uri.UnescapeDataString(parts[1]); targetName = Uri.UnescapeDataString(parts[2]); } else if (parts.Length == 2) { uriStr = parts[0]; parameter = Uri.UnescapeDataString(parts[1]); } var uri = new Uri(uriStr, UriKind.RelativeOrAbsolute); var link = new Hyperlink(); // assign ICommand instance if available, otherwise set NavigateUri ICommand command; if (this.Commands != null && this.Commands.TryGetValue(uri, out command)) { link.Command = command; link.CommandParameter = parameter; if (targetName != null) { link.CommandTarget = this.source.FindName(targetName) as IInputElement; } } else { link.NavigateUri = uri; link.TargetName = parameter; } parent = link; span.Inlines.Add(parent); } var run = context.CreateRun(token.Value); parent.Inlines.Add(run); } else if (token.TokenType == BBCodeLexer.TokenLineBreak) { span.Inlines.Add(new LineBreak()); } else if (token.TokenType == BBCodeLexer.TokenAttribute) { throw new ParseException("Unexpected token"); } else if (token.TokenType == BBCodeLexer.TokenEnd) { break; } else { throw new ParseException("Unexpected token type"); } } }
private void Parse(Span span) { ParseContext context = new ParseContext(span); while (true) { Token token = LA(1); Consume(); if (token.TokenType == BBCodeLexer.TokenStartTag) { Span parent = span; if (token.Value == TagListItem) { if (context.IsFirstListItem) { context.IsFirstListItem = false; parent.Inlines.Add(new LineBreak()); } parent.Inlines.Add( new Run(string.Format("\u0020\u0020{0}\u0020\u0020", context.IsOrderedList ? string.Format("{0}.", ++context.ListCounter) : "\u2022"))); } ParseTag(token.Value, true, context); } else if (token.TokenType == BBCodeLexer.TokenEndTag) { Span parent = span; if (context.IsListItem && token.Value == TagListItem) { parent.Inlines.Add(new LineBreak()); } ParseTag(token.Value, false, context); } else if (token.TokenType == BBCodeLexer.TokenText) { Span parent = span; Uri uri; string parameter = null; string targetName = null; // parse uri value for optional parameter and/or target, eg [url=cmd://foo|parameter|target] if (NavigationHelper.TryParseUriWithParameters(context.NavigateUri, out uri, out parameter, out targetName)) { Hyperlink link = new Hyperlink(); // assign ICommand instance if available, otherwise set NavigateUri ICommand command; if (Commands != null && Commands.TryGetValue(uri, out command)) { link.Command = command; link.CommandParameter = parameter; if (targetName != null) { link.CommandTarget = source.FindName(targetName) as IInputElement; } } else { link.NavigateUri = uri; link.TargetName = parameter; } parent = link; if (context.Foreground != null) { link.Foreground = context.Foreground; } span.Inlines.Add(parent); } if (context.IsListItem) { parent.Inlines.Add(context.CreateRun(token.Value)); } else { Run run = context.CreateRun(token.Value); parent.Inlines.Add(run); } } else if (token.TokenType == BBCodeLexer.TokenLineBreak) { span.Inlines.Add(new LineBreak()); } else if (token.TokenType == BBCodeLexer.TokenAttribute) { throw new ParseException(Resources.UnexpectedToken); } else if (token.TokenType == Lexer.TokenEnd) { break; } else { throw new ParseException(Resources.UnknownTokenType); } } }
private void Parse(Span span) { var context = new ParseContext(span); while (true) { var token = La(1); Consume(); if (token.TokenType == BBCodeLexer.TokenStartTag) { ParseTag(token.Value, true, context); } else if (token.TokenType == BBCodeLexer.TokenEndTag) { ParseTag(token.Value, false, context); } else if (token.TokenType == BBCodeLexer.TokenText) { var parent = span; if (context.NavigateUri != null) { var uriStr = context.NavigateUri; string parameter = null; string targetName = null; var parts = uriStr.Split(new[] { '|' }, 3); if (parts.Length == 3) { uriStr = parts[0]; parameter = Uri.UnescapeDataString(parts[1]); targetName = Uri.UnescapeDataString(parts[2]); } else if (parts.Length == 2) { uriStr = parts[0]; parameter = Uri.UnescapeDataString(parts[1]); } var uri = new Uri(uriStr, UriKind.RelativeOrAbsolute); var link = new Hyperlink(); ICommand command; if (Commands != null && Commands.TryGetValue(uri, out command)) { link.Command = command; link.CommandParameter = parameter; if (targetName != null) { link.CommandTarget = _source.FindName(targetName) as IInputElement; } } else { link.NavigateUri = uri; link.TargetName = parameter; } parent = link; span.Inlines.Add(parent); } var run = context.CreateRun(token.Value); parent.Inlines.Add(run); } else if (token.TokenType == BBCodeLexer.TokenLineBreak) { span.Inlines.Add(new LineBreak()); } else if (token.TokenType == BBCodeLexer.TokenAttribute) { throw new ParseException(Resources.UnexpectedToken); } else if (token.TokenType == Lexer.TokenEnd) { break; } else { throw new ParseException(Resources.UnknownTokenType); } } }