diff options
Diffstat (limited to 'src/main/java/org/zwobble')
3 files changed, 52 insertions, 10 deletions
diff --git a/src/main/java/org/zwobble/mammoth/internal/docx/Numbering.java b/src/main/java/org/zwobble/mammoth/internal/docx/Numbering.java index 90ea5c1..8d29393 100644 --- a/src/main/java/org/zwobble/mammoth/internal/docx/Numbering.java +++ b/src/main/java/org/zwobble/mammoth/internal/docx/Numbering.java @@ -4,21 +4,47 @@ import org.zwobble.mammoth.internal.documents.NumberingLevel; import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; import static org.zwobble.mammoth.internal.util.Maps.lookup; import static org.zwobble.mammoth.internal.util.Maps.map; public class Numbering { + public static class AbstractNum { - private final Map<String, NumberingLevel> levels; + private final Map<String, AbstractNumLevel> levels; private final Optional<String> numStyleLink; - public AbstractNum(Map<String, NumberingLevel> levels, Optional<String> numStyleLink) { + public AbstractNum(Map<String, AbstractNumLevel> levels, Optional<String> numStyleLink) { this.levels = levels; this.numStyleLink = numStyleLink; } } + public static class AbstractNumLevel { + public static AbstractNumLevel ordered(String levelIndex) { + return new AbstractNumLevel(levelIndex, true, Optional.empty()); + } + + public static AbstractNumLevel unordered(String levelIndex) { + return new AbstractNumLevel(levelIndex, false, Optional.empty()); + } + + private final String levelIndex; + private final boolean isOrdered; + private final Optional<String> paragraphStyleId; + + public AbstractNumLevel(String levelIndex, boolean isOrdered, Optional<String> paragraphStyleId) { + this.levelIndex = levelIndex; + this.isOrdered = isOrdered; + this.paragraphStyleId = paragraphStyleId; + } + + public NumberingLevel toNumberingLevel() { + return new NumberingLevel(levelIndex, isOrdered); + } + } + public static class Num { private final Optional<String> abstractNumId; @@ -30,6 +56,7 @@ public class Numbering { public static final Numbering EMPTY = new Numbering(map(), map(), Styles.EMPTY); private final Map<String, AbstractNum> abstractNums; + private final Map<String, AbstractNumLevel> levelsByParagraphStyleId; private final Map<String, Num> nums; private final Styles styles; @@ -39,6 +66,10 @@ public class Numbering { Styles styles ) { this.abstractNums = abstractNums; + this.levelsByParagraphStyleId = abstractNums.values().stream() + .flatMap(abstractNum -> abstractNum.levels.values().stream()) + .filter(level -> level.paragraphStyleId.isPresent()) + .collect(Collectors.toMap(level -> level.paragraphStyleId.get(), level -> level)); this.nums = nums; this.styles = styles; } @@ -54,8 +85,12 @@ public class Numbering { .flatMap(style -> style.getNumId()) .flatMap(linkedNumId -> findLevel(linkedNumId, level)); } else { - return lookup(abstractNum.levels, level); + return lookup(abstractNum.levels, level).map(value -> value.toNumberingLevel()); } }); } + + public Optional<NumberingLevel> findLevelByParagraphStyleId(String styleId) { + return lookup(levelsByParagraphStyleId, styleId).map(value -> value.toNumberingLevel()); + } } diff --git a/src/main/java/org/zwobble/mammoth/internal/docx/NumberingXml.java b/src/main/java/org/zwobble/mammoth/internal/docx/NumberingXml.java index b25ffdd..5f811db 100644 --- a/src/main/java/org/zwobble/mammoth/internal/docx/NumberingXml.java +++ b/src/main/java/org/zwobble/mammoth/internal/docx/NumberingXml.java @@ -1,6 +1,5 @@ package org.zwobble.mammoth.internal.docx; -import org.zwobble.mammoth.internal.documents.NumberingLevel; import org.zwobble.mammoth.internal.xml.XmlElement; import org.zwobble.mammoth.internal.xml.XmlElementList; @@ -31,15 +30,16 @@ public class NumberingXml { return entry(abstractNumId, abstractNum); } - private static Map<String, NumberingLevel> readAbstractNumLevels(XmlElement element) { + private static Map<String, Numbering.AbstractNumLevel> readAbstractNumLevels(XmlElement element) { return toMap(element.findChildren("w:lvl"), NumberingXml::readAbstractNumLevel); } - private static Map.Entry<String, NumberingLevel> readAbstractNumLevel(XmlElement element) { + private static Map.Entry<String, Numbering.AbstractNumLevel> readAbstractNumLevel(XmlElement element) { String levelIndex = element.getAttribute("w:ilvl"); Optional<String> numFmt = element.findChildOrEmpty("w:numFmt").getAttributeOrNone("w:val"); boolean isOrdered = !numFmt.equals(Optional.of("bullet")); - return entry(levelIndex, new NumberingLevel(levelIndex, isOrdered)); + Optional<String> paragraphStyleId = element.findChildOrEmpty("w:pStyle").getAttributeOrNone("w:val"); + return entry(levelIndex, new Numbering.AbstractNumLevel(levelIndex, isOrdered, paragraphStyleId)); } private static Map<String, Numbering.Num> readNums(XmlElementList numElements) { diff --git a/src/main/java/org/zwobble/mammoth/internal/docx/StatefulBodyXmlReader.java b/src/main/java/org/zwobble/mammoth/internal/docx/StatefulBodyXmlReader.java index 9c270de..0cf141e 100644 --- a/src/main/java/org/zwobble/mammoth/internal/docx/StatefulBodyXmlReader.java +++ b/src/main/java/org/zwobble/mammoth/internal/docx/StatefulBodyXmlReader.java @@ -256,12 +256,11 @@ class StatefulBodyXmlReader { private ReadResult readParagraph(XmlElement element) { XmlElementLike properties = element.findChildOrEmpty("w:pPr"); - Optional<NumberingLevel> numbering = readNumbering(properties); ParagraphIndent indent = readParagraphIndent(properties); return ReadResult.map( readParagraphStyle(properties), readElements(element.getChildren()), - (style, children) -> new Paragraph(style, numbering, indent, children)).appendExtra(); + (style, children) -> new Paragraph(style, readNumbering(style, properties), indent, children)).appendExtra(); } private ReadResult readFieldChar(XmlElement element) { @@ -328,7 +327,15 @@ class StatefulBodyXmlReader { } - private Optional<NumberingLevel> readNumbering(XmlElementLike properties) { + private Optional<NumberingLevel> readNumbering(Optional<Style> style, XmlElementLike properties) { + if (style.isPresent()) { + String styleId = style.get().getStyleId(); + Optional<NumberingLevel> level = numbering.findLevelByParagraphStyleId(styleId); + if (level.isPresent()) { + return level; + } + } + XmlElementLike numberingProperties = properties.findChildOrEmpty("w:numPr"); return Optionals.flatMap( readVal(numberingProperties, "w:numId"), |
