Пример #1
0
        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);
                }
            }
        }
Пример #2
0
        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");
                }
            }
        }
Пример #4
0
        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);
                }
            }
        }
Пример #5
0
        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);
                }
            }
        }