Skip to content

Bugfix: Look for the paragraph number properties in the style as well #251

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions Xceed.Words.NET/Src/Container.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) )
Expand Down Expand Up @@ -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 );
}
}

Expand Down
132 changes: 100 additions & 32 deletions Xceed.Words.NET/Src/Paragraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -36,7 +37,7 @@ public class Paragraph : InsertBeforeOrAfter
// The Append family of functions use this List to apply style.
internal List<XElement> _runs;
internal int _startIndex, _endIndex;
internal List<XElement> _styles = new List<XElement>();
internal XElement _style;

internal const float DefaultLineSpacing = 1.1f * 20.0f;

Expand Down Expand Up @@ -817,6 +818,13 @@ public bool IsKeepWithNext
}
}

public XElement Style
{
get
{
return _style;
}
}

#endregion

Expand All @@ -831,41 +839,86 @@ 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 );

if ( _style != null )
{
string parentStyleName = GetParentStyleName( _style );
while ( parentStyleName != null )
{
XElement parentStyle = FindStyle( styles_element, parentStyleName );
MergeStyleElements( _style, parentStyle );
parentStyleName = GetParentStyleName( parentStyle );
}
}
}
}

_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;
}

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
Expand Down Expand Up @@ -4755,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;
}

Expand Down