From 0eae6fdab4896a3df6c1aeb807982296b70e47f9 Mon Sep 17 00:00:00 2001 From: ROM-Knowledgeware Date: Wed, 25 Jul 2018 14:53:52 +0300 Subject: [PATCH 1/2] Paragraph: replace the _styles variable with a more appropriate _style variable and populate it --- Xceed.Words.NET/Src/Container.cs | 12 ++--- Xceed.Words.NET/Src/Paragraph.cs | 76 ++++++++++++++++++-------------- 2 files changed, 48 insertions(+), 40 deletions(-) diff --git a/Xceed.Words.NET/Src/Container.cs b/Xceed.Words.NET/Src/Container.cs index bf39da6a..975a1c58 100644 --- a/Xceed.Words.NET/Src/Container.cs +++ b/Xceed.Words.NET/Src/Container.cs @@ -477,7 +477,7 @@ public virtual Paragraph InsertParagraph( Paragraph p ) #region Styles XDocument style_document; - if( p._styles.Count() > 0 ) + if( p.Style != null ) { var style_package_uri = new Uri( "/word/styles.xml", UriKind.Relative ); if( !Document._package.PartExists( style_package_uri ) ) @@ -506,14 +506,10 @@ public virtual Paragraph InsertParagraph( Paragraph p ) where a != null select a.Value; - foreach( XElement style in p._styles ) + // If styles_element does not contain this element, then add it. + if ( !ids.Contains( p.Style.Attribute( XName.Get( "styleId", DocX.w.NamespaceName ) ).Value ) ) { - // If styles_element does not contain this element, then add it. - - if( !ids.Contains( style.Attribute( XName.Get( "styleId", DocX.w.NamespaceName ) ).Value ) ) - { - styles_element.Add( style ); - } + styles_element.Add( p.Style ); } } diff --git a/Xceed.Words.NET/Src/Paragraph.cs b/Xceed.Words.NET/Src/Paragraph.cs index fb2e9efb..ec379c0b 100644 --- a/Xceed.Words.NET/Src/Paragraph.cs +++ b/Xceed.Words.NET/Src/Paragraph.cs @@ -19,6 +19,7 @@ This program is provided to you under the terms of the Microsoft Public using System.Xml.Linq; using System.Text.RegularExpressions; using System.Security.Principal; +using System.IO; using System.IO.Packaging; using System.Drawing; using System.Globalization; @@ -36,7 +37,7 @@ public class Paragraph : InsertBeforeOrAfter // The Append family of functions use this List to apply style. internal List _runs; internal int _startIndex, _endIndex; - internal List _styles = new List(); + internal XElement _style; internal const float DefaultLineSpacing = 1.1f * 20.0f; @@ -817,6 +818,13 @@ public bool IsKeepWithNext } } + public XElement Style + { + get + { + return _style; + } + } #endregion @@ -831,41 +839,45 @@ internal Paragraph( DocX document, XElement xml, int startIndex, ContainerType p RebuildDocProperties(); - //// Check if this Paragraph references any pStyle elements. - //var stylesElements = xml.Descendants( XName.Get( "pStyle", DocX.w.NamespaceName ) ); - - //// If one or more pStyles are referenced. - //if( stylesElements.Count() > 0 ) - //{ - // Uri style_package_uri = new Uri( "/word/styles.xml", UriKind.Relative ); - // PackagePart styles_document = document.package.GetPart( style_package_uri ); - - // using( TextReader tr = new StreamReader( styles_document.GetStream() ) ) - // { - // XDocument style_document = XDocument.Load( tr ); - // XElement styles_element = style_document.Element( XName.Get( "styles", DocX.w.NamespaceName ) ); - - // var styles_element_ids = stylesElements.Select( e => e.Attribute( XName.Get( "val", DocX.w.NamespaceName ) ).Value ); - - // //foreach(string id in styles_element_ids) - // //{ - // // var style = - // // ( - // // from d in styles_element.Descendants() - // // let styleId = d.Attribute(XName.Get("styleId", DocX.w.NamespaceName)) - // // let type = d.Attribute(XName.Get("type", DocX.w.NamespaceName)) - // // where type != null && type.Value == "paragraph" && styleId != null && styleId.Value == id - // // select d - // // ).First(); - - // // styles.Add(style); - // //} - // } - //} + // Check if this Paragraph references a pStyle element. + var styleElement = xml.Descendants( XName.Get( "pStyle", DocX.w.NamespaceName ) ).FirstOrDefault(); + + // If a pStyle is referenced. + if( styleElement != null ) + { + string styleElementID = styleElement.Attribute( XName.Get( "val" , DocX.w.NamespaceName ) ).Value; + + Uri style_package_uri = new Uri( "/word/styles.xml", UriKind.Relative ); + PackagePart styles_document = document._package.GetPart( style_package_uri ); + + using( TextReader tr = new StreamReader( styles_document.GetStream() ) ) + { + XDocument style_document = XDocument.Load( tr ); + XElement styles_element = style_document.Element( XName.Get( "styles", DocX.w.NamespaceName ) ); + + _style = FindStyle( styles_element, styleElementID ); + } + } _runs = Xml.Elements( XName.Get( "r", DocX.w.NamespaceName ) ).ToList(); } + internal static XElement FindStyle(XElement styles_element, string styleElementID) + { + foreach (XElement style in styles_element.Elements()) + { + XAttribute styleId = style.Attribute(XName.Get("styleId", DocX.w.NamespaceName)); + XAttribute type = style.Attribute(XName.Get("type", DocX.w.NamespaceName)); + if (type != null && type.Value == "paragraph" && + styleId != null && styleId.Value == styleElementID) + { + return style; + } + } + + return null; + } + #endregion #region Public Methods From 306368af14fecea24ecfb6bc98edec90a5dc5322 Mon Sep 17 00:00:00 2001 From: ROM-Knowledgeware Date: Wed, 25 Jul 2018 15:07:24 +0300 Subject: [PATCH 2/2] Bugfix: Look for the paragraph number properties in the style as well --- Xceed.Words.NET/Src/Paragraph.cs | 56 ++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/Xceed.Words.NET/Src/Paragraph.cs b/Xceed.Words.NET/Src/Paragraph.cs index ec379c0b..bffa15ab 100644 --- a/Xceed.Words.NET/Src/Paragraph.cs +++ b/Xceed.Words.NET/Src/Paragraph.cs @@ -856,6 +856,17 @@ internal Paragraph( DocX document, XElement xml, int startIndex, ContainerType p XElement styles_element = style_document.Element( XName.Get( "styles", DocX.w.NamespaceName ) ); _style = FindStyle( styles_element, styleElementID ); + + if ( _style != null ) + { + string parentStyleName = GetParentStyleName( _style ); + while ( parentStyleName != null ) + { + XElement parentStyle = FindStyle( styles_element, parentStyleName ); + MergeStyleElements( _style, parentStyle ); + parentStyleName = GetParentStyleName( parentStyle ); + } + } } } @@ -878,6 +889,36 @@ internal static XElement FindStyle(XElement styles_element, string styleElementI return null; } + internal static string GetParentStyleName(XElement style) + { + XElement basedOn = style.Elements(XName.Get("basedOn", DocX.w.NamespaceName)).FirstOrDefault(); + if (basedOn != null) + { + XAttribute val = basedOn.Attribute(XName.Get("val", DocX.w.NamespaceName)); + if (val != null) + { + return val.Value; + } + } + return null; + } + + internal static void MergeStyleElements(XElement style, XElement parentStyle) + { + foreach (XElement parentElement in parentStyle.Elements()) + { + XElement element = style.Element(parentElement.Name); + if (element == null) + { + style.Add(parentElement); + } + else + { + MergeStyleElements(element, parentElement); + } + } + } + #endregion #region Public Methods @@ -4767,6 +4808,21 @@ from xml in Xml.Descendants( XName.Get( "fldSimple", DocX.w.NamespaceName ) ) private XElement GetParagraphNumberProperties() { var numPrNode = Xml.Descendants().FirstOrDefault( el => el.Name.LocalName == "numPr" ); + if ( numPrNode != null ) + { + var numIdNode = Xml.Descendants().First( s => s.Name.LocalName == "numId" ); + var numId = Int32.Parse( numIdNode.Attribute( DocX.w + "val" ).Value ); + if ( numId == 0 ) + { + // ECMA-376-1: 17.9.18 numId: A value of 0 for the val attribute shall [..] be used to designate the + // removal of numbering properties at a particular level in the style hierarchy. + return null; + } + } + else if ( _style != null ) + { + numPrNode = _style.Descendants().FirstOrDefault( el => el.Name.LocalName == "numPr" ); + } return numPrNode; }