/** * Follow the resolution rules to return the paragraph properties which actually apply, given this * pPr element (on a w:p). * * <p>Note 1: the properties are not the definition of any style name returned. Note 2: run * properties are not resolved or returned by this method. * * <p>What is returned is a live object. If you want to change it, you should clone it first! * * @param expressPPr * @return */ public PPr getEffectivePPr(PPr expressPPr) { PPr effectivePPr = null; // First, the document defaults are applied // Done elsewhere // PPr effectivePPr = (PPr)XmlUtils.deepCopy(documentDefaultPPr); // Next, the table style properties are applied to each table in the document, // following the conditional formatting inclusions and exclusions specified // per table. // TODO - if the paragraph is in a table? // Next, numbered item and paragraph properties are applied to each paragraph // formatted with a *numbering *style**. // TODO - who uses numbering styles (as opposed to numbering // via a paragraph style or direct formatting)? // Next, paragraph and run properties are // applied to each paragraph as defined by the paragraph style. PPr resolvedPPr = null; String styleId; if (expressPPr == null || expressPPr.getPStyle() == null) { // styleId = "Normal"; styleId = defaultParagraphStyleId; } else { styleId = expressPPr.getPStyle().getVal(); } resolvedPPr = getEffectivePPr(styleId); // Next, run properties are applied to each run with a specific character style // applied. // Not for pPr // Finally, we apply direct formatting (paragraph or run properties not from // styles). if (hasDirectPPrFormatting(expressPPr)) { if (resolvedPPr == null) { log.warn("resolvedPPr was null. Look into this?"); effectivePPr = Context.getWmlObjectFactory().createPPr(); } else { effectivePPr = (PPr) XmlUtils.deepCopy(resolvedPPr); } applyPPr(expressPPr, effectivePPr); return effectivePPr; } else { return resolvedPPr; } }
@Override public List<Object> apply(Object o) { if (o instanceof org.docx4j.wml.P) { pPr = ((P) o).getPPr(); if (stylesInUse != null) { // do the styles boolean customPStyle = false; if (pPr != null) { if (pPr.getPStyle() != null) { // Note this paragraph style // log.debug("put style " + pPr.getPStyle().getVal()); customPStyle = true; stylesInUse.add(pPr.getPStyle().getVal()); } if ((pPr.getRPr() != null) && (pPr.getRPr().getRStyle() != null)) { // Note this run style // log.debug("put style " + pPr.getRPr().getRStyle().getVal() ); stylesInUse.add(pPr.getRPr().getRStyle().getVal()); } } defaultParagraphStyleUsed = defaultParagraphStyleUsed || (!customPStyle); } } else if (o instanceof org.docx4j.wml.R) { rPr = ((R) o).getRPr(); if (stylesInUse != null) { if (rPr != null) { if (rPr.getRStyle() == null) { defaultCharacterStyleUsed = true; } else { stylesInUse.add(rPr.getRStyle().getVal()); } } } } else if (o instanceof org.docx4j.wml.Text) { if (runFontSelector != null) { // discover the fonts which apply to this text log.debug(((Text) o).getValue()); runFontSelector.fontSelector(pPr, rPr, ((Text) o)); } } else if (o instanceof org.docx4j.wml.R.Sym) { if (fontsDiscovered != null) { org.docx4j.wml.R.Sym sym = (org.docx4j.wml.R.Sym) o; fontsDiscovered.add(sym.getFont()); } } else if (o instanceof org.docx4j.wml.Tbl) { // The table could have a table style; // Tables created in Word 2007 default to table style "TableGrid", // which is based on "TableNormal". org.docx4j.wml.Tbl tbl = (org.docx4j.wml.Tbl) o; if (stylesInUse != null && tbl.getTblPr() != null && tbl.getTblPr().getTblStyle() != null) { // log.debug("Adding table style: " + tbl.getTblPr().getTblStyle().getVal() ); stylesInUse.add(tbl.getTblPr().getTblStyle().getVal()); } // There is no such thing as a tr or a tc style, // so we don't need to look for them, // but since a tc can contain w:p or nested table, // we still need to recurse } return null; }
/** * @param expressRPr * @param pPr - * @return */ public RPr getEffectiveRPr(RPr expressRPr, PPr pPr) { // NB Currently used in PDF viaXSLFO only log.debug("in getEffectiveRPr"); // Idea is that you pass pPr if you are using this for XSL FO, // since we need to take account of rPr in paragraph styles // (but not the rPr in a pPr direct formatting, since // that only applies to the paragraph mark). // * For HTML/CSS, this would be null (since the pPr level rPr // * is made into a separate style applied via a second value in // * the class attribute). But, in the CSS case, this // function is not used - since the rPr is made into a style as well. // First, the document defaults are applied RPr effectiveRPr = (RPr) XmlUtils.deepCopy(documentDefaultRPr); // Apply DefaultParagraphFont. We only do it explicitly // here as per conditions, because if there is a run style, // walking the hierarchy will include this if it is needed if (expressRPr == null || expressRPr.getRStyle() == null) { applyRPr(resolvedStyleRPrComponent.get(defaultCharacterStyleId), effectiveRPr); } // Next, the table style properties are applied to each table in the document, // following the conditional formatting inclusions and exclusions specified // per table. // TODO - if the paragraph is in a table? // Next, numbered item and paragraph properties are applied to each paragraph // formatted with a *numbering *style**. // TODO - who uses numbering styles (as opposed to numbering // via a paragraph style or direct formatting)? // Next, paragraph and run properties are // applied to each paragraph as defined by the paragraph style // (this includes run properties defined in a paragraph style, // but not run properties directly included in a pPr in the // document (those only apply to a paragraph mark). if (pPr == null) { log.debug("pPr was null"); } else { // At the pPr level, what rPr do we have? // .. ascend the paragraph style tree if (pPr.getPStyle() == null) { // log.warn("No pstyle:"); // log.debug(XmlUtils.marshaltoString(pPr, true, true)); } else { log.debug("pstyle:" + pPr.getPStyle().getVal()); RPr pPrLevelRunStyle = getEffectiveRPr(pPr.getPStyle().getVal()); // .. and apply those applyRPr(pPrLevelRunStyle, effectiveRPr); } // Check Paragraph rPr (our special hack of using ParaRPr // to format a fo:block) if ((expressRPr == null) && (pPr.getRPr() != null) && (hasDirectRPrFormatting(pPr.getRPr()))) { applyRPr(pPr.getRPr(), effectiveRPr); } } // Next, run properties are applied to each run with a specific character style // applied. RPr resolvedRPr = null; String runStyleId; if (expressRPr != null && expressRPr.getRStyle() != null) { runStyleId = expressRPr.getRStyle().getVal(); resolvedRPr = getEffectiveRPr(runStyleId); applyRPr(resolvedRPr, effectiveRPr); } // Finally, we apply direct formatting (run properties not from // styles). if (hasDirectRPrFormatting(expressRPr)) { // effectiveRPr = (RPr)XmlUtils.deepCopy(effectiveRPr); applyRPr(expressRPr, effectiveRPr); } return effectiveRPr; }