예제 #1
0
        /// <summary>
        /// Replaces a tag inside a paragraph (a:p) with parsed HTML
        /// </summary>
        /// <param name="p">The paragraph (a:p).</param>
        /// <param name="tag">The tag to replace by newText, if null or empty do nothing; tag is a regex string.</param>
        /// <param name="newText">The new text to replace the tag with, if null replaced by empty string and not visible.</param>
        /// <param name="fontName">Font name</param>
        /// <param name="fontSize">Font size. E.g. 800 is 8pt (small) font. If value is less than 100 it will be multiplied by 100 to keep up with PPT notation.</param>
        /// <param name="hyperlinks">URL Relationships dictionary. Relationship has to be defined on slide level.</param>
        /// <returns><c>true</c> if a tag has been found and replaced, <c>false</c> otherwise.</returns>
        internal static bool ReplaceTagWithHtml(A.Paragraph p, string tag, string newText, string fontName = null, int fontSize = 0, IDictionary <string, string> hyperlinks = null)
        {
            newText = CorrectUnhandledHtmlTags(newText); // e.g. deal with ul/li html tags
            bool isFirstLine = true;                     // avoiding unintentional empty line at the begining of the text
            bool replaced    = false;

            string[] closingTags = new string[] { "div", "p" }; // tags that force line break in PPTX paragraph

            if (string.IsNullOrEmpty(tag))
            {
                return(replaced);
            }

            if (newText == null)
            {
                newText = string.Empty;
            }
            newText = RemoveInvalidXMLChars(newText);

            while (true)
            {
                // Search for the tag
                Match match = Regex.Match(GetTexts(p), tag);
                if (!match.Success)
                {
                    break;
                }

                p.RemoveAllChildren(); // // remove exisitng children then add new

                HtmlParser hp = new HtmlParser(newText);
                MariGold.HtmlParser.IHtmlNode nodes = null;

                try
                {
                    nodes = hp.FindBodyOrFirstElement();
                }
                catch
                {
                    Console.WriteLine(String.Format("WARNING: HTML is empty or HTML schema has errors. Parsed HTML[]: [{0}]", newText));
                }

                while (nodes != null)
                {
                    foreach (var item in nodes.Children)
                    {
                        bool  skipLineBreak = false;
                        A.Run r             = new A.Run();
                        r.RunProperties = new A.RunProperties();

                        if (item.Html.Contains("<b>") || item.Html.Contains("<strong>"))
                        {
                            r.RunProperties.Bold = new DocumentFormat.OpenXml.BooleanValue(true);
                        }
                        if (item.Html.Contains("<i>") || item.Html.Contains("<em>"))
                        {
                            r.RunProperties.Italic = new DocumentFormat.OpenXml.BooleanValue(true);
                        }
                        if (item.Html.Contains("<u>") || item.Html.Contains("text-decoration: underline"))
                        {
                            r.RunProperties.Underline = new DocumentFormat.OpenXml.EnumValue <A.TextUnderlineValues>(A.TextUnderlineValues.Dash);
                        }
                        if (item.Html.Contains("<a"))
                        {
                            string uriId = null;
                            try
                            {
                                string url = PptxSlide.ParseHttpUrls(item.Html).First().Value;
                                uriId = hyperlinks.Where(q => q.Value == url).FirstOrDefault().Key;
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("URL is no available");
                            }
                            if (uriId != null)
                            {
                                A.HyperlinkOnClick link = new A.HyperlinkOnClick()
                                {
                                    Id = uriId
                                };
                                r.RunProperties.AppendChild(link);
                            }
                        }

                        A.Text at = new A.Text(PptxTemplater.TextTransformationHelper.HtmlToPlainTxt(item.InnerHtml) + " "); // clear not interpreted html tags
                        if (at.InnerText.Trim() == "" && isFirstLine)
                        {
                            at          = new A.Text(); // avoid excessive new lines
                            isFirstLine = false;
                        }
                        r.AppendChild(at);
                        p.Append(r);

                        // LINE BREAK -- if outer tag is div add line break
                        if (closingTags.Contains(item.Parent.Tag) && skipLineBreak == false)
                        {
                            p.Append(new A.Break());
                        }
                    }

                    // remove parsed html part
                    newText = newText.Substring(nodes.Html.Length);
                    if (newText.Trim() == "")
                    {
                        break;
                    }
                    hp    = new HtmlParser(newText);
                    nodes = hp.FindBodyOrFirstElement();
                }

                var run = p.Descendants <A.Run>();
                foreach (var item in run)
                {
                    if (fontName != null)
                    {
                        item.RunProperties.RemoveAllChildren <A.LatinFont>();
                        var latinFont = new A.LatinFont();
                        latinFont.Typeface = fontName;
                        item.RunProperties.AppendChild(latinFont);
                    }
                    if (fontSize > 0)
                    {
                        item.RunProperties.FontSize = (fontSize > 99) ? fontSize : fontSize * 100; // e.g. translate value 8 (Power Point UI font size) to 800 for API
                    }
                }

                replaced = true;
            }

            return(replaced);
        }