public static void AssembleFormatting(WordprocessingDocument wDoc, FormattingAssemblerSettings settings)
 {
     FormattingAssemblerInfo fai = new FormattingAssemblerInfo();
     XDocument sXDoc = wDoc.MainDocumentPart.StyleDefinitionsPart.GetXDocument();
     XElement defaultParagraphStyle = sXDoc
         .Root
         .Elements(W.style)
         .FirstOrDefault(st => st.Attribute(W._default).ToBoolean() == true &&
             (string)st.Attribute(W.type) == "paragraph");
     if (defaultParagraphStyle != null)
         fai.DefaultParagraphStyleName = (string)defaultParagraphStyle.Attribute(W.styleId);
     XElement defaultCharacterStyle = sXDoc
         .Root
         .Elements(W.style)
         .FirstOrDefault(st => st.Attribute(W._default).ToBoolean() == true &&
             (string)st.Attribute(W.type) == "character");
     if (defaultCharacterStyle != null)
         fai.DefaultCharacterStyleName = (string)defaultCharacterStyle.Attribute(W.styleId);
     XElement defaultTableStyle = sXDoc
         .Root
         .Elements(W.style)
         .FirstOrDefault(st => st.Attribute(W._default).ToBoolean() == true &&
             (string)st.Attribute(W.type) == "table");
     if (defaultTableStyle != null)
         fai.DefaultTableStyleName = (string)defaultTableStyle.Attribute(W.styleId);
     ListItemRetrieverSettings listItemRetrieverSettings = new ListItemRetrieverSettings();
     AssembleListItemInformation(wDoc, settings.ListItemRetrieverSettings);
     foreach (var part in wDoc.ContentParts())
     {
         var pxd = part.GetXDocument();
         FixNonconformantHexValues(pxd.Root);
         AnnotateWithGlobalDefaults(wDoc, pxd.Root, settings);
         AnnotateTablesWithTableStyles(wDoc, pxd.Root);
         AnnotateParagraphs(fai, wDoc, pxd.Root, settings);
         AnnotateRuns(fai, wDoc, pxd.Root, settings);
     }
     NormalizeListItems(fai, wDoc, settings);
     if (settings.ClearStyles)
         ClearStyles(wDoc);
     foreach (var part in wDoc.ContentParts())
     {
         var pxd = part.GetXDocument();
         pxd.Root.Descendants().Attributes().Where(a => a.IsNamespaceDeclaration).Remove();
         FormattingAssembler.NormalizePropsForPart(pxd, settings);
         var newRoot = (XElement)CleanupTransform(pxd.Root);
         pxd.Root.ReplaceWith(newRoot);
         part.PutXDocument();
     }
 }
        private static object NormalizeListItemsTransform(FormattingAssemblerInfo fai, WordprocessingDocument wDoc, XNode node, FormattingAssemblerSettings settings)
        {
            var element = node as XElement;
            if (element != null)
            {
                if (element.Name == W.p)
                {
                    var li = ListItemRetriever.RetrieveListItem(wDoc, element, settings.ListItemRetrieverSettings);
                    if (li != null)
                    {
                        ListItemRetriever.ListItemInfo listItemInfo = element.Annotation<ListItemRetriever.ListItemInfo>();

                        var newParaProps = new XElement(W.pPr,
                            element.Elements(W.pPr).Elements().Where(e => e.Name != W.numPr)
                        );

                        XElement listItemRunProps = null;
                        int? abstractNumId = null;
                        if (listItemInfo != null)
                        {
                            abstractNumId = listItemInfo.AbstractNumId;

                            var paraStyleRunProps = CharStyleRollup(fai, wDoc, element);

                            var paragraphStyleName = (string)element
                                .Elements(W.pPr)
                                .Elements(W.pStyle)
                                .Attributes(W.val)
                                .FirstOrDefault();

                            string defaultStyleName = (string)wDoc
                                    .MainDocumentPart
                                    .StyleDefinitionsPart
                                    .GetXDocument()
                                    .Root
                                    .Elements(W.style)
                                    .Where(s => (string)s.Attribute(W.type) == "paragraph" && s.Attribute(W._default).ToBoolean() == true)
                                    .Attributes(W.styleId)
                                    .FirstOrDefault();

                            if (paragraphStyleName == null)
                                paragraphStyleName = defaultStyleName;

                            XDocument stylesXDoc = wDoc
                                .MainDocumentPart
                                .StyleDefinitionsPart
                                .GetXDocument();

                            // put together run props for list item.

                            XElement lvlStyleRpr = ParaStyleRunPropsStack(wDoc, paragraphStyleName)
                                .Aggregate(new XElement(W.rPr),
                                    (r, s) =>
                                    {
                                        var newCharStyleRunProps = MergeStyleElement(s, r);
                                        return newCharStyleRunProps;
                                    });

                            var mergedRunProps = MergeStyleElement(lvlStyleRpr, paraStyleRunProps);

                            var accumulatedRunProps = element.Elements(PtOpenXml.pPr).Elements(W.rPr).FirstOrDefault();
                            if (accumulatedRunProps != null)
                                mergedRunProps = MergeStyleElement(accumulatedRunProps, mergedRunProps);

                            var listItemLvl = listItemInfo.Lvl(ListItemRetriever.GetParagraphLevel(element));
                            var listItemLvlRunProps = listItemLvl.Elements(W.rPr).FirstOrDefault();
                            listItemRunProps = MergeStyleElement(listItemLvlRunProps, mergedRunProps);

                            if ((string)listItemLvl.Elements(W.numFmt).Attributes(W.val).FirstOrDefault() == "bullet")
                            {
                                listItemRunProps.Elements(W.rtl).Remove();
                            }
                            else
                            {
                                var pPr = element.Element(PtOpenXml.pPr);
                                if (pPr != null)
                                {
                                    XElement bidiel = pPr.Element(W.bidi);
                                    bool bidi = bidiel != null && (bidiel.Attribute(W.val) == null || bidiel.Attribute(W.val).ToBoolean() == true);
                                    if (bidi)
                                    {
                                        listItemRunProps = MergeStyleElement(new XElement(W.rPr,
                                            new XElement(W.rtl)), listItemRunProps);
                                    }
                                }
                            }
                        }

                        var listItemRun = new XElement(W.r,
                            element.Attribute(PtOpenXml.FontName),
                            element.Attribute(PtOpenXml.LanguageType),
                            listItemRunProps,
                            new XElement(W.t,
                                new XAttribute(XNamespace.Xml + "space", "preserve"),
                                li));

                        AdjustFontAttributes(wDoc, listItemRun, null, listItemRunProps, settings);

                        var lvl = listItemInfo.Lvl(ListItemRetriever.GetParagraphLevel(element));
                        XElement suffix = new XElement(W.tab);
                        var su = (string)lvl.Elements(W.suff).Attributes(W.val).FirstOrDefault();
                        if (su == "space")
                            suffix = new XElement(W.t,
                                new XAttribute(XNamespace.Xml + "space", "preserve"),
                                " ");
                        else if (su == "nothing")
                            suffix = null;

                        var jc = (string)lvl.Elements(W.lvlJc).Attributes(W.val).FirstOrDefault();
                        if (jc == "right")
                        {
                            var accumulatedParaProps = element.Element(PtOpenXml.pPr);

                            var hangingAtt = accumulatedParaProps.Elements(W.ind).Attributes(W.hanging).FirstOrDefault();
                            if (hangingAtt == null)
                            {
                                var listItemRunLength = WordprocessingMLUtil.CalcWidthOfRunInTwips(listItemRun);
                                var ind = accumulatedParaProps.Element(W.ind);
                                if (ind == null)
                                {
                                    ind = new XElement(W.ind);
                                    accumulatedParaProps.Add(ind);
                                }
                                ind.Add(new XAttribute(W.hanging, listItemRunLength.ToString()));
                            }
                            else
                            {
                                var hanging = (int)hangingAtt;
                                var listItemRunLength = WordprocessingMLUtil.CalcWidthOfRunInTwips(listItemRun);
                                hanging += listItemRunLength; // should be width of list item, in twips
                                hangingAtt.Value = hanging.ToString();
                            }
                        }
                        else if (jc == "center")
                        {
                            var accumulatedParaProps = element.Element(PtOpenXml.pPr);

                            var hangingAtt = accumulatedParaProps.Elements(W.ind).Attributes(W.hanging).FirstOrDefault();
                            if (hangingAtt == null)
                            {
                                var listItemRunLength = WordprocessingMLUtil.CalcWidthOfRunInTwips(listItemRun);
                                var ind = accumulatedParaProps.Element(W.ind);
                                if (ind == null)
                                {
                                    ind = new XElement(W.ind);
                                    accumulatedParaProps.Add(ind);
                                }
                                ind.Add(new XAttribute(W.hanging, (listItemRunLength / 2).ToString()));
                            }
                            else
                            {
                                var hanging = (int)hangingAtt;
                                var listItemRunLength = WordprocessingMLUtil.CalcWidthOfRunInTwips(listItemRun);
                                hanging += (listItemRunLength / 2); // should be half of width of list item, in twips
                                hangingAtt.Value = hanging.ToString();
                            }
                        }
                        AddTabAtLeftIndent(element.Element(PtOpenXml.pPr));

                        XElement newPara = new XElement(W.p,
                            element.Attribute(PtOpenXml.FontName),
                            element.Attribute(PtOpenXml.LanguageType),
                            new XAttribute(PtOpenXml.AbstractNumId, abstractNumId),
                            newParaProps,
                            listItemRun,
                            suffix != null ?
                                new XElement(W.r,
                                    listItemRunProps,
                                    suffix) : null,
                            element.Elements().Where(e => e.Name != W.pPr).Select(n => NormalizeListItemsTransform(fai, wDoc, n, settings)));
                        return newPara;

                    }
                }

                return new XElement(element.Name,
                    element.Attributes(),
                    element.Nodes().Select(n => NormalizeListItemsTransform(fai, wDoc, n, settings)));
            }
            return node;
        }
        private static XElement CharStyleRollup(FormattingAssemblerInfo fai, WordprocessingDocument wDoc, XElement runOrPara)
        {
            var sXDoc = wDoc.MainDocumentPart.StyleDefinitionsPart.GetXDocument();

            string charStyle = null;
            string paraStyle = null;
            XElement rPr = null;
            XElement pPr = null;
            XElement pStyle = null;
            XElement rStyle = null;
            CachedParaInfo cpi = null; // CachedParaInfo is an optimization for the case where a paragraph contains thousands of runs.

            if (runOrPara.Name == W.p)
            {
                cpi = runOrPara.Annotation<CachedParaInfo>();
                if (cpi != null)
                    pPr = cpi.ParagraphProperties;
                else
                {
                    pPr = runOrPara.Element(W.pPr);
                    if (pPr != null)
                    {
                        paraStyle = (string)pPr.Elements(W.pStyle).Attributes(W.val).FirstOrDefault();
                    }
                    else
                    {
                        paraStyle = fai.DefaultParagraphStyleName;
                    }
                    cpi = new CachedParaInfo
                    {
                        ParagraphProperties = pPr,
                        ParagraphStyleName = paraStyle,
                    };
                    runOrPara.AddAnnotation(cpi);
                }
                if (pPr != null)
                {
                    rPr = pPr.Element(W.rPr);
                }
            }
            else
            {
                rPr = runOrPara.Element(W.rPr);
            }
            if (rPr != null)
            {
                rStyle = rPr.Element(W.rStyle);
                if (rStyle != null)
                {
                    charStyle = (string)rStyle.Attribute(W.val);
                }
                else
                {
                    if (runOrPara.Name == W.r)
                        charStyle = (string)runOrPara
                            .Ancestors(W.p)
                            .Take(1)
                            .Elements(W.pPr)
                            .Elements(W.pStyle)
                            .Attributes(W.val)
                            .FirstOrDefault();
                    else
                        charStyle = (string)runOrPara
                            .Elements(W.pPr)
                            .Elements(W.pStyle)
                            .Attributes(W.val)
                            .FirstOrDefault();
                }
            }

            if (charStyle == null)
            {
                if (runOrPara.Name == W.r)
                {
                    var ancestorPara = runOrPara.Ancestors(W.p).First();
                    cpi = ancestorPara.Annotation<CachedParaInfo>();
                    if (cpi != null)
                        charStyle = cpi.ParagraphStyleName;
                    else
                        charStyle = (string)runOrPara.Ancestors(W.p).First().Elements(W.pPr).Elements(W.pStyle).Attributes(W.val).FirstOrDefault();
                }
                if (charStyle == null)
                {
                    charStyle = fai.DefaultParagraphStyleName;
                }
            }

            // A run always must have an ancestor paragraph.
            XElement para = null;
            var rolledUpParaStyleRunProps = new XElement(W.rPr);
            if (runOrPara.Name == W.r)
            {
                para = runOrPara.Ancestors(W.p).FirstOrDefault();
            }
            else
            {
                para = runOrPara;
            }

            cpi = para.Annotation<CachedParaInfo>();
            if (cpi != null)
            {
                pPr = cpi.ParagraphProperties;
            }
            else
            {
                pPr = para.Element(W.pPr);
            }
            if (pPr != null)
            {
                pStyle = pPr.Element(W.pStyle);
                if (pStyle != null)
                {
                    paraStyle = (string)pStyle.Attribute(W.val);
                }
                else
                {
                    paraStyle = fai.DefaultParagraphStyleName;
                }
            }
            else
                paraStyle = fai.DefaultParagraphStyleName;

            string key = (paraStyle == null ? "[null]" : paraStyle) + "~|~" +
                (charStyle == null ? "[null]" : charStyle);
            XElement rolledRunProps = null;

            if (fai.RolledCharacterStyles.ContainsKey(key))
                rolledRunProps = fai.RolledCharacterStyles[key];
            else
            {
                XElement rolledUpCharStyleRunProps = new XElement(W.rPr);
                if (charStyle != null)
                {
                    rolledUpCharStyleRunProps =
                        CharStyleStack(wDoc, charStyle)
                            .Aggregate(new XElement(W.rPr),
                                (r, s) =>
                                {
                                    var newRunProps = MergeStyleElement(s, r);
                                    return newRunProps;
                                });
                }

                if (paraStyle != null)
                {
                    rolledUpParaStyleRunProps = ParaStyleRunPropsStack(wDoc, paraStyle)
                        .Aggregate(new XElement(W.rPr),
                            (r, s) =>
                            {
                                var newCharStyleRunProps = MergeStyleElement(s, r);
                                return newCharStyleRunProps;
                            });
                }
                rolledRunProps = MergeStyleElement(rolledUpCharStyleRunProps, rolledUpParaStyleRunProps);
                fai.RolledCharacterStyles.Add(key, rolledRunProps);
            }

            return rolledRunProps;
        }
        private static void AnnotateRunProperties(FormattingAssemblerInfo fai, WordprocessingDocument wDoc, XElement runOrPara, FormattingAssemblerSettings settings)
        {
            XElement localRunProps = null;
            if (runOrPara.Name == W.p)
            {
                var rPr = runOrPara.Elements(W.pPr).Elements(W.rPr).FirstOrDefault();
                if (rPr != null)
                {
                    localRunProps = rPr;
                }
            }
            else
            {
                localRunProps = runOrPara.Element(W.rPr);
            }
            if (localRunProps == null)
            {
                localRunProps = new XElement(W.rPr);
            }

            // get run table props, to be merged.
            XElement tablerPr = null;
            var blockLevelContentContainer = runOrPara
                .Ancestors()
                .FirstOrDefault(a => a.Name == W.body ||
                    a.Name == W.tbl ||
                    a.Name == W.txbxContent ||
                    a.Name == W.ftr ||
                    a.Name == W.hdr ||
                    a.Name == W.footnote ||
                    a.Name == W.endnote);
            if (blockLevelContentContainer.Name == W.tbl)
            {
                XElement tbl = blockLevelContentContainer;
                XElement style = tbl.Element(PtOpenXml.pt + "style");
                XElement cellCnf = runOrPara.Ancestors(W.tc).Take(1).Elements(W.tcPr).Elements(W.cnfStyle).FirstOrDefault();
                XElement rowCnf = runOrPara.Ancestors(W.tr).Take(1).Elements(W.trPr).Elements(W.cnfStyle).FirstOrDefault();

                if (style != null)
                {
                    tablerPr = style.Element(W.rPr);
                    if (tablerPr == null)
                        tablerPr = new XElement(W.rPr);

                    foreach (var ot in TableStyleOverrideTypes)
                    {
                        XName attName = TableStyleOverrideXNameMap[ot];
                        if ((cellCnf != null && cellCnf.Attribute(attName).ToBoolean() == true) ||
                            (rowCnf != null && rowCnf.Attribute(attName).ToBoolean() == true))
                        {
                            XElement o = style
                                .Elements(W.tblStylePr)
                                .Where(tsp => (string)tsp.Attribute(W.type) == ot)
                                .FirstOrDefault();
                            if (o != null)
                            {
                                XElement otrPr = o.Element(W.rPr);
                                tablerPr = MergeStyleElement(otrPr, tablerPr);
                            }
                        }
                    }
                }
            }
            XElement rolledRunProps = CharStyleRollup(fai, wDoc, runOrPara);
            var toggledRunProps = ToggleMergeRunProps(rolledRunProps, tablerPr);
            var currentRunProps = runOrPara.Element(PtOpenXml.rPr); // this is already stored on the run from previous aggregation of props
            var mergedRunProps = MergeStyleElement(toggledRunProps, currentRunProps);
            var newMergedRunProps = MergeStyleElement(localRunProps, mergedRunProps);
            XElement pPr = null;
            if (runOrPara.Name == W.p)
                pPr = runOrPara.Element(PtOpenXml.pPr);
            AdjustFontAttributes(wDoc, runOrPara, pPr, newMergedRunProps, settings);

            newMergedRunProps.Name = PtOpenXml.rPr;
            if (currentRunProps != null)
            {
                currentRunProps.ReplaceWith(newMergedRunProps);
            }
            else
            {
                runOrPara.Add(newMergedRunProps);
            }
        }
 private static void AnnotateRuns(FormattingAssemblerInfo fai, WordprocessingDocument wDoc, XElement root, FormattingAssemblerSettings settings)
 {
     var runsOrParas = root.Descendants()
         .Where(rp =>
         {
             return rp.Name == W.r || rp.Name == W.p;
         });
     foreach (var runOrPara in runsOrParas)
     {
         AnnotateRunProperties(fai, wDoc, runOrPara, settings);
     }
 }
 private static void NormalizeListItems(FormattingAssemblerInfo fai, WordprocessingDocument wDoc, FormattingAssemblerSettings settings)
 {
     foreach (var part in wDoc.ContentParts())
     {
         var pxd = part.GetXDocument();
         XElement newRoot = (XElement)NormalizeListItemsTransform(fai, wDoc, pxd.Root, settings);
         if (newRoot.Attribute(XNamespace.Xmlns + "pt14") == null)
             newRoot.Add(new XAttribute(XNamespace.Xmlns + "pt14", PtOpenXml.pt.NamespaceName));
         if (newRoot.Attribute(XNamespace.Xmlns + "mc") == null)
             newRoot.Add(new XAttribute(XNamespace.Xmlns + "mc", MC.mc.NamespaceName));
         pxd.Root.ReplaceWith(newRoot);
     }
 }
        private static void AnnotateParagraph(FormattingAssemblerInfo fai, WordprocessingDocument wDoc, XElement para, FormattingAssemblerSettings settings)
        {
            XElement localParaProps = para.Element(W.pPr);
            if (localParaProps == null)
            {
                localParaProps = new XElement(W.pPr);
            }

            // get para table props, to be merged.
            XElement tablepPr = null;

            var blockLevelContentContainer = para
                .Ancestors()
                .FirstOrDefault(a => a.Name == W.body ||
                    a.Name == W.tbl ||
                    a.Name == W.txbxContent ||
                    a.Name == W.ftr ||
                    a.Name == W.hdr ||
                    a.Name == W.footnote ||
                    a.Name == W.endnote);
            if (blockLevelContentContainer.Name == W.tbl)
            {
                XElement tbl = blockLevelContentContainer;
                XElement style = tbl.Element(PtOpenXml.pt + "style");
                XElement cellCnf = para.Ancestors(W.tc).Take(1).Elements(W.tcPr).Elements(W.cnfStyle).FirstOrDefault();
                XElement rowCnf = para.Ancestors(W.tr).Take(1).Elements(W.trPr).Elements(W.cnfStyle).FirstOrDefault();

                if (style != null)
                {
                    // roll up tblPr, trPr, and tcPr from within a specific style.
                    // add each of these to the table, in PowerTools namespace.
                    tablepPr = style.Element(W.pPr);
                    if (tablepPr == null)
                        tablepPr = new XElement(W.pPr);

                    foreach (var ot in TableStyleOverrideTypes)
                    {
                        XName attName = TableStyleOverrideXNameMap[ot];
                        if ((cellCnf != null && cellCnf.Attribute(attName).ToBoolean() == true) ||
                            (rowCnf != null && rowCnf.Attribute(attName).ToBoolean() == true))
                        {
                            XElement o = style
                                .Elements(W.tblStylePr)
                                .Where(tsp => (string)tsp.Attribute(W.type) == ot)
                                .FirstOrDefault();
                            if (o != null)
                            {
                                XElement otpPr = o.Element(W.pPr);
                                tablepPr = MergeStyleElement(otpPr, tablepPr);
                            }
                        }
                    }
                }
            }
            var stylesPart = wDoc.MainDocumentPart.StyleDefinitionsPart;
            XDocument sXDoc = null;
            if (stylesPart != null)
                sXDoc = stylesPart.GetXDocument();

            ListItemRetriever.ListItemInfo lif = para.Annotation<ListItemRetriever.ListItemInfo>();

            XElement rolledParaProps = ParagraphStyleRollup(para, sXDoc, fai.DefaultParagraphStyleName);
            if (lif != null && lif.IsZeroNumId)
                rolledParaProps.Elements(W.ind).Remove();
            XElement toggledParaProps = MergeStyleElement(rolledParaProps, tablepPr);
            XElement mergedParaProps = MergeStyleElement(localParaProps, toggledParaProps);

            string li = ListItemRetriever.RetrieveListItem(wDoc, para, settings.ListItemRetrieverSettings);
            if (lif != null && lif.IsListItem)
            {
                if (settings.RestrictToSupportedNumberingFormats)
                {
                    string numFmtForLevel = (string)lif.Lvl(ListItemRetriever.GetParagraphLevel(para)).Elements(W.numFmt).Attributes(W.val).FirstOrDefault();
                    if (numFmtForLevel == null)
                    {
                        var numFmtElement = lif.Lvl(ListItemRetriever.GetParagraphLevel(para)).Elements(MC.AlternateContent).Elements(MC.Choice).Elements(W.numFmt).FirstOrDefault();
                        if (numFmtElement != null && (string)numFmtElement.Attribute(W.val) == "custom")
                            numFmtForLevel = (string)numFmtElement.Attribute(W.format);
                    }
                    bool isLgl = lif.Lvl(ListItemRetriever.GetParagraphLevel(para)).Elements(W.isLgl).Any();
                    if (isLgl && numFmtForLevel != "decimalZero")
                        numFmtForLevel = "decimal";
                    if (!AcceptableNumFormats.Contains(numFmtForLevel))
                        throw new UnsupportedNumberingFormatException(numFmtForLevel + " is not a supported numbering format");
                }

                int paragraphLevel = ListItemRetriever.GetParagraphLevel(para);
                var numberingParaProps = lif
                    .Lvl(paragraphLevel)
                    .Elements(W.pPr)
                    .FirstOrDefault();
                if (numberingParaProps == null)
                {
                    numberingParaProps = new XElement(W.pPr);
                }
                else
                {
                    numberingParaProps
                        .Elements()
                        .Where(e => e.Name != W.ind)
                        .Remove();
                }

                // have:
                // - localParaProps
                // - toggledParaProps
                // - numberingParaProps

                // if a paragraph contains a numPr with a numId=0, in other words, it is NOT a numbered item, then the indentation from the style
                // hierarchy is ignored.

                ListItemRetriever.ListItemInfo lii = para.Annotation<ListItemRetriever.ListItemInfo>();
                if (lii.FromParagraph != null)
                {
                    // order
                    // - toggledParaProps
                    // - numberingParaProps
                    // - localParaProps

                    mergedParaProps = MergeStyleElement(numberingParaProps, toggledParaProps);
                    mergedParaProps = MergeStyleElement(localParaProps, mergedParaProps);
                }
                else if (lii.FromStyle != null)
                {
                    // order
                    // - numberingParaProps
                    // - toggledParaProps
                    // - localParaProps
                    mergedParaProps = MergeStyleElement(toggledParaProps, numberingParaProps);
                    mergedParaProps = MergeStyleElement(localParaProps, mergedParaProps);
                }
            }
            else
            {
                mergedParaProps = MergeStyleElement(localParaProps, toggledParaProps);
            }

            // merge mergedParaProps with existing accumulatedParaProps, with mergedParaProps as high pri
            // replace accumulatedParaProps with newly merged

            XElement accumulatedParaProps = para.Element(PtOpenXml.pt + "pPr");
            XElement newAccumulatedParaProps = MergeStyleElement(mergedParaProps, accumulatedParaProps);

            AdjustFontAttributes(wDoc, para, newAccumulatedParaProps, newAccumulatedParaProps.Element(W.rPr), settings);
            newAccumulatedParaProps.Name = PtOpenXml.pt + "pPr";
            if (accumulatedParaProps != null)
            {
                accumulatedParaProps.ReplaceWith(newAccumulatedParaProps);
            }
            else
            {
                para.Add(newAccumulatedParaProps);
            }
        }
 private static void AnnotateParagraphs(FormattingAssemblerInfo fai, WordprocessingDocument wDoc, XElement root, FormattingAssemblerSettings settings)
 {
     foreach (var para in root.Descendants(W.p))
     {
         AnnotateParagraph(fai, wDoc, para, settings);
     }
 }