Ejemplo n.º 1
0
        /// <summary>
        /// Main function for parsing process
        /// </summary>
        /// <param name="text">text to parse</param>
        /// <param name="baseForeColor">base Font color</param>
        /// <param name="baseFont">base font</param>
        /// <param name="fontSize">base font size</param>
        /// <param name="aligment">base textaligment</param>
        /// <param name="fontStyle"> base font style etc. Regular, Bold</param>
        /// <returns>Formatted text block that contains the whole structure</returns>
        public static FormattedTextBlock Parse(string text, Color baseForeColor, string baseFont, float fontSize, FontStyle fontStyle, ContentAlignment aligment)
        {
            if (string.IsNullOrEmpty(text))
            {
                return(new FormattedTextBlock());
            }

            Stack <FormattedText.HTMLLikeListType> lastListType = new Stack <FormattedText.HTMLLikeListType>();

            lastListType.Push(FormattedText.HTMLLikeListType.None);
            text = text.Replace("\\<", "&lt;").Replace("\\>", "&gt;").Replace("\r\n", "<br>").Replace("\n", "<br>");

            //prepare initially block
            FormattedTextBlock textBlock             = new FormattedTextBlock();
            FormattedText      previousFormattedText = new FormattedText();//this is a base item for creating HTML

            previousFormattedText.FontColor        = baseForeColor;
            previousFormattedText.FontName         = baseFont;
            previousFormattedText.FontSize         = fontSize;
            previousFormattedText.ContentAlignment = aligment;
            previousFormattedText.FontStyle        = fontStyle;

            //create tokens
            StringTokenizer tokenizer   = new StringTokenizer(text, "<");
            int             count       = tokenizer.Count();
            bool            hasOpenTag  = text.IndexOf("<") > -1;
            TextLine        currentLine = new TextLine();

            textBlock.Lines.Add(currentLine);
            bool shouldProduceNewLine = false;

            TinyHTMLParsersData parsersData = new TinyHTMLParsersData();

            //enumerate tokens
            for (int i = 0; i < count; ++i)
            {
                FormattedText currentItem = ProcessToken(ref previousFormattedText, tokenizer, hasOpenTag, parsersData, ref shouldProduceNewLine);

                if (!string.IsNullOrEmpty(currentItem.HtmlTag) &&
                    currentItem.HtmlTag.Length >= 1 && shouldProduceNewLine)
                {
                    currentLine = new TextLine();
                    textBlock.Lines.Add(currentLine);
                    if (currentItem.HtmlTag.Length >= 2)
                    {
                        currentItem.HtmlTag = currentItem.HtmlTag.TrimEnd(' ').Trim('/');
                    }

                    shouldProduceNewLine = (!string.IsNullOrEmpty(currentItem.text) && currentItem.text.Trim().Length == 0);
                }

                currentLine.List.Add(currentItem);
                previousFormattedText = new FormattedText(currentItem);
            }

            return(textBlock);
        }
Ejemplo n.º 2
0
        private static void ProcessSpan(ref FormattedText currentFormattedText,
                                        string lowerHtmlTag,
                                        string htmlTag,
                                        bool isClosingTag,
                                        TinyHTMLParsersData parserData)
        {
            if (isClosingTag)
            {
                if (parserData.lastFormattedText.Count > 0)
                {
                    currentFormattedText = parserData.lastFormattedText.Pop();
                    currentFormattedText.ShouldDisplayBullet = false;
                }

                return;
            }

            parserData.lastFormattedText.Push(new FormattedText(currentFormattedText));
            string style = ParseAttribute(htmlTag, lowerHtmlTag, "style");
            string value = ProcessStyle(style, "color");

            if (!string.IsNullOrEmpty(value))
            {
                currentFormattedText.FontColor = ParseColor(value, currentFormattedText.FontColor);
            }

            value = ProcessStyle(style, "background-color");
            if (!string.IsNullOrEmpty(value))
            {
                currentFormattedText.BgColor = ParseColor(value, currentFormattedText.BgColor);
            }

            value = ProcessStyle(style, "font-family");
            if (!string.IsNullOrEmpty(value))
            {
                currentFormattedText.FontName = ParseFont(value);
            }

            value = ProcessStyle(style, "font-size");
            if (!string.IsNullOrEmpty(value))
            {
                currentFormattedText.FontSize = ParseNumber(value, currentFormattedText.FontSize);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// process single token from Html string
        /// </summary>
        /// <param name="prevItem"></param>
        /// <param name="tokenizer"></param>
        /// <param name="hasOpenTag"></param>
        /// <param name="parserData"></param>
        /// <param name="shouldProduceNewLine"></param>
        /// <returns>a FormattedText object</returns>
        private static FormattedText ProcessToken(ref FormattedText prevItem,
                                                  StringTokenizer tokenizer,
                                                  bool hasOpenTag,
                                                  TinyHTMLParsersData parserData,
                                                  ref bool shouldProduceNewLine)
        {
            string          currentToken   = tokenizer.NextToken(); //text block
            StringTokenizer currentCommand = new StringTokenizer(currentToken, ">");
            bool            hasCloseTag    = currentToken.IndexOf(">") > -1;
            string          htmlTag        = currentCommand.NextToken();
            string          text           = currentCommand.NextToken();
            FormattedText   item           = new FormattedText(prevItem);

            if (!hasOpenTag || !hasCloseTag)
            {
                item.text    = htmlTag; //only text without htmlTag
                item.HtmlTag = string.Empty;
            }
            else
            {
                bool isKnowCommand = ApplyHTMLSettingsFromTag(ref item, prevItem, htmlTag, parserData, ref shouldProduceNewLine, ref text);
                if (isKnowCommand)
                {
                    item.text = text;
                }
                else
                {
                    item.text = htmlTag + text;
                }

                item.HtmlTag = htmlTag;
            }

            if (!string.IsNullOrEmpty(item.text))
            {
                item.text = item.text.Replace("&lt;", "<").Replace("&gt;", ">");
            }

            item.StartNewLine = shouldProduceNewLine;
            return(item);
        }
Ejemplo n.º 4
0
        private static void ProcessSingleListEntry(bool isCloseTag, ref int numberCount, FormattedText currentFormattedText, TinyHTMLParsersData parserData)
        {
            FormattedText.HTMLLikeListType listType = parserData.lastListType.Peek();
            currentFormattedText.ShouldDisplayBullet = !isCloseTag;
            if (listType != FormattedText.HTMLLikeListType.OrderedList)
            {
                return;
            }

            if (!isCloseTag)
            {
                ++numberCount;
            }

            currentFormattedText.Number = numberCount;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Parse single HTML tag and apply settings
        /// </summary>
        /// <param name="currentFormattedText"></param>
        /// <param name="prevText"></param>
        /// <param name="htmlTag"></param>
        /// <param name="parserData"></param>
        /// <param name="shouldProduceNewLine"></param>
        /// <param name="text"></param>
        public static bool ApplyHTMLSettingsFromTag(ref FormattedText currentFormattedText,
                                                    FormattedText prevText,
                                                    string htmlTag,
                                                    TinyHTMLParsersData parserData,
                                                    ref bool shouldProduceNewLine,
                                                    ref string text)
        {
            if (string.IsNullOrEmpty(htmlTag))
            {
                return(true);
            }

            htmlTag = htmlTag.Trim('<', '>');
            bool isClosingTag = htmlTag.StartsWith("/");

            currentFormattedText.IsClosingTag = isClosingTag;
            if (isClosingTag)
            {
                htmlTag = htmlTag.TrimStart('/');
            }

            string lowerHtmlTag  = htmlTag.ToLower();
            bool   isKnowCommand = true;

            if (lowerHtmlTag == "i" || lowerHtmlTag == "em")
            {
                currentFormattedText.FontStyle = ProcessFontStyle(currentFormattedText.FontStyle, FontStyle.Italic, isClosingTag);
            }
            else if (lowerHtmlTag == "b" || lowerHtmlTag == "strong")
            {
                currentFormattedText.FontStyle = ProcessFontStyle(currentFormattedText.FontStyle, FontStyle.Bold, isClosingTag);
            }
            else if (lowerHtmlTag == "u")
            {
                currentFormattedText.FontStyle = ProcessFontStyle(currentFormattedText.FontStyle, FontStyle.Underline, isClosingTag);
            }
            else if (lowerHtmlTag.StartsWith("color") && htmlTag.Length > 6)
            {
                currentFormattedText.FontColor = ParseColor(htmlTag.Substring(6), currentFormattedText.FontColor);
            }
            else if (lowerHtmlTag.StartsWith("size=") || lowerHtmlTag.StartsWith("size ="))
            {
                currentFormattedText.FontSize = ParseSize(htmlTag, prevText.FontSize);
            }
            else if ((lowerHtmlTag.StartsWith("font=") || lowerHtmlTag.StartsWith("font =")) && htmlTag.Length > 5)
            {
                currentFormattedText.FontName = ParseFont(htmlTag.Substring(5));
            }
            else if (lowerHtmlTag == "strike")
            {
                currentFormattedText.FontStyle = ProcessFontStyle(currentFormattedText.FontStyle, FontStyle.Strikeout, isClosingTag);
            }
            else if (lowerHtmlTag.StartsWith("bgcolor"))
            {
                currentFormattedText.BgColor = ProcessBgColor(lowerHtmlTag, currentFormattedText.BgColor, isClosingTag);
            }
            //lists
            else if (lowerHtmlTag == "ul")
            {
                ProcessListEntry(isClosingTag, FormattedText.HTMLLikeListType.List, parserData.lastListType, parserData.lastListNumberCount, currentFormattedText);
            }
            else if (lowerHtmlTag == "ol")
            {
                ProcessListEntry(isClosingTag, FormattedText.HTMLLikeListType.OrderedList, parserData.lastListType, parserData.lastListNumberCount, currentFormattedText);
            }
            else if (lowerHtmlTag == "li")
            {
                int lastNumber = 0;
                shouldProduceNewLine = !shouldProduceNewLine && !isClosingTag;
                if (parserData.lastListNumberCount.Count > 0)
                {
                    lastNumber = parserData.lastListNumberCount.Pop();
                }

                if (parserData.lastListType.Count > 0)
                {
                    ProcessSingleListEntry(isClosingTag, ref lastNumber, currentFormattedText, parserData);
                }

                parserData.lastListNumberCount.Push(lastNumber);
            }
            //end lists
            else if (lowerHtmlTag == "html")
            {
            }
            else if (lowerHtmlTag == "br" || lowerHtmlTag == "br /" || lowerHtmlTag == "br/")
            {
                shouldProduceNewLine = !isClosingTag;
            }
            else if (lowerHtmlTag == "p")
            {
                if (isClosingTag)
                {
                    shouldProduceNewLine = false;
                }
                else
                {
                    if (!prevText.IsClosingTag &&
                        !prevText.StartNewLine)
                    {
                        shouldProduceNewLine = !shouldProduceNewLine;
                    }
                }
            }
            else if (lowerHtmlTag.StartsWith("img "))
            {
                string imageName = ParseAttribute(htmlTag, lowerHtmlTag, "src");
                string width     = ParseAttribute(htmlTag, lowerHtmlTag, "width");
                string height    = ParseAttribute(htmlTag, lowerHtmlTag, "height");

                SetImage(imageName, width, height, currentFormattedText);
            }
            else if (lowerHtmlTag.StartsWith("a"))
            {
                ProcessLink(currentFormattedText, htmlTag, lowerHtmlTag, isClosingTag, ref text);
            }
            else if (lowerHtmlTag.StartsWith("span"))
            {
                ProcessSpan(ref currentFormattedText, lowerHtmlTag, htmlTag, isClosingTag, parserData);
            }
            else
            {
                isKnowCommand = false;
            }

            //if (parserData.shouldClearProduceBullets)
            //{
            //    currentFormattedText.ShouldDisplayBullet = false;
            //    parserData.shouldClearProduceBullets = false;
            //}

            return(isKnowCommand);
        }