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; import java.util.Map; import java.util.Optional; import static org.zwobble.mammoth.internal.util.Maps.entry; import static org.zwobble.mammoth.internal.util.Maps.toMap; public class NumberingXml { public static Numbering readNumberingXmlElement(XmlElement element, Styles styles) { Map abstractNums = readAbstractNums(element.findChildren("w:abstractNum")); Map nums = readNums(element.findChildren("w:num")); return new Numbering(abstractNums, nums, styles); } private static Map readAbstractNums(XmlElementList children) { return toMap(children, NumberingXml::readAbstractNum); } private static Map.Entry readAbstractNum(XmlElement element) { // TODO: in python-mammoth, we allow None here. Check whether that's actually possible or not String abstractNumId = element.getAttribute("w:abstractNumId"); Numbering.AbstractNum abstractNum = new Numbering.AbstractNum( readAbstractNumLevels(element), element.findChildOrEmpty("w:numStyleLink").getAttributeOrNone("w:val") ); return entry(abstractNumId, abstractNum); } private static Map readAbstractNumLevels(XmlElement element) { return toMap(element.findChildren("w:lvl"), NumberingXml::readAbstractNumLevel); } private static Map.Entry readAbstractNumLevel(XmlElement element) { String levelIndex = element.getAttribute("w:ilvl"); Optional numFmt = element.findChildOrEmpty("w:numFmt").getAttributeOrNone("w:val"); boolean isOrdered = !numFmt.equals(Optional.of("bullet")); return entry(levelIndex, new NumberingLevel(levelIndex, isOrdered)); } private static Map readNums(XmlElementList numElements) { return toMap(numElements, NumberingXml::readNum); } private static Map.Entry readNum(XmlElement numElement) { // TODO: in python-mammoth, we allow None here. Check whether that's actually possible or not String numId = numElement.getAttribute("w:numId"); Optional abstractNumId = numElement.findChildOrEmpty("w:abstractNumId").getAttributeOrNone("w:val"); return entry(numId, new Numbering.Num(abstractNumId)); } }