| 1 | package pro.verron.officestamper.asciidoc; | |
| 2 | ||
| 3 | import jakarta.xml.bind.JAXBElement; | |
| 4 | import org.docx4j.TextUtils; | |
| 5 | import org.docx4j.com.microsoft.schemas.office.drawing.x2016.SVG.main.CTSVGBlip; | |
| 6 | import org.docx4j.dml.CTOfficeArtExtensionList; | |
| 7 | import org.docx4j.dml.Graphic; | |
| 8 | import org.docx4j.dml.picture.Pic; | |
| 9 | import org.docx4j.dml.wordprocessingDrawing.Anchor; | |
| 10 | import org.docx4j.dml.wordprocessingDrawing.Inline; | |
| 11 | import org.docx4j.model.structure.HeaderFooterPolicy; | |
| 12 | import org.docx4j.model.structure.SectionWrapper; | |
| 13 | import org.docx4j.openpackaging.exceptions.Docx4JException; | |
| 14 | import org.docx4j.openpackaging.packages.WordprocessingMLPackage; | |
| 15 | import org.docx4j.openpackaging.parts.WordprocessingML.CommentsPart; | |
| 16 | import org.docx4j.openpackaging.parts.WordprocessingML.FooterPart; | |
| 17 | import org.docx4j.openpackaging.parts.WordprocessingML.HeaderPart; | |
| 18 | import org.docx4j.openpackaging.parts.WordprocessingML.StyleDefinitionsPart; | |
| 19 | import org.docx4j.vml.CTTextbox; | |
| 20 | import org.docx4j.wml.*; | |
| 21 | import org.docx4j.wml.PPrBase.PStyle; | |
| 22 | import org.jspecify.annotations.Nullable; | |
| 23 | import org.slf4j.Logger; | |
| 24 | import org.slf4j.LoggerFactory; | |
| 25 | ||
| 26 | import java.math.BigInteger; | |
| 27 | import java.util.*; | |
| 28 | import java.util.function.Function; | |
| 29 | import java.util.stream.Collectors; | |
| 30 | import java.util.stream.Stream; | |
| 31 | ||
| 32 | import static java.util.Optional.ofNullable; | |
| 33 | import static pro.verron.officestamper.asciidoc.AsciiDocModel.of; | |
| 34 | ||
| 35 | /// Minimal DOCX → AsciiDoc text extractor used by tests. This intentionally mirrors a subset of the legacy Stringifier | |
| 36 | /// formatting for: | |
| 37 | /// - Paragraphs | |
| 38 | /// - Tables (|=== fences, each cell prefixed with '|') | |
| 39 | /// - Basic inline text extraction More advanced features (headers/footers, breaks, styles) can be added incrementally | |
| 40 | /// as needed by tests. | |
| 41 | public final class DocxToAsciiDoc | |
| 42 | implements Function<WordprocessingMLPackage, AsciiDocModel> { | |
| 43 | private static final String SVG_EXTENSION = "{96DAC541-7B7A-43D3-8B79-37D633B846F1}"; | |
| 44 | private static final Logger log = LoggerFactory.getLogger(DocxToAsciiDoc.class); | |
| 45 | ||
| 46 | private final StyleDefinitionsPart styleDefinitionsPart; | |
| 47 | private final CommentRecorder commentRecorder; | |
| 48 | private final BlockRecorder blocks; | |
| 49 | private final WordprocessingMLPackage wordprocessingMLPackage; | |
| 50 | private final CommentsPart commentsPart; | |
| 51 | ||
| 52 | /// Constructs a new DocxToAsciiDoc instance, initializing necessary components for converting a | |
| 53 | /// WordprocessingMLPackage (Docx) document into AsciiDoc format. This constructor extracts and prepares | |
| 54 | /// the main document part, style definitions part, comments part, and other required components for processing. | |
| 55 | /// | |
| 56 | /// @param pkg the WordprocessingMLPackage instance representing the Docx document to be converted | |
| 57 | public DocxToAsciiDoc(WordprocessingMLPackage pkg) { | |
| 58 | this.wordprocessingMLPackage = pkg; | |
| 59 | var mdp = wordprocessingMLPackage.getMainDocumentPart(); | |
| 60 | this.styleDefinitionsPart = mdp.getStyleDefinitionsPart(true); | |
| 61 | this.commentsPart = mdp.getCommentsPart(); | |
| 62 | this.commentRecorder = new CommentRecorder(commentsPart); | |
| 63 | this.blocks = new BlockRecorder(); | |
| 64 | } | |
| 65 | ||
| 66 | private static Stream<HeaderPart> getHeaderParts(WordprocessingMLPackage document) { | |
| 67 | var sections = document.getDocumentModel() | |
| 68 | .getSections(); | |
| 69 | ||
| 70 | var set = new LinkedHashSet<HeaderPart>(); | |
| 71 | for (SectionWrapper section : sections) { | |
| 72 | HeaderFooterPolicy hfp = section.getHeaderFooterPolicy(); | |
| 73 |
1
1. getHeaderParts : negated conditional → SURVIVED |
if (hfp != null) { |
| 74 |
1
1. getHeaderParts : negated conditional → KILLED |
if (hfp.getFirstHeader() != null) set.add(hfp.getFirstHeader()); |
| 75 |
1
1. getHeaderParts : negated conditional → KILLED |
if (hfp.getDefaultHeader() != null) set.add(hfp.getDefaultHeader()); |
| 76 |
1
1. getHeaderParts : negated conditional → KILLED |
if (hfp.getEvenHeader() != null) set.add(hfp.getEvenHeader()); |
| 77 | } | |
| 78 | } | |
| 79 |
1
1. getHeaderParts : replaced return value with Stream.empty for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::getHeaderParts → SURVIVED |
return set.stream(); |
| 80 | } | |
| 81 | ||
| 82 | private static Stream<FooterPart> getFooterParts(WordprocessingMLPackage document) { | |
| 83 | var sections = document.getDocumentModel() | |
| 84 | .getSections(); | |
| 85 | ||
| 86 | var set = new LinkedHashSet<FooterPart>(); | |
| 87 | for (SectionWrapper section : sections) { | |
| 88 | HeaderFooterPolicy hfp = section.getHeaderFooterPolicy(); | |
| 89 |
1
1. getFooterParts : negated conditional → SURVIVED |
if (hfp != null) { |
| 90 |
1
1. getFooterParts : negated conditional → KILLED |
if (hfp.getFirstFooter() != null) set.add(hfp.getFirstFooter()); |
| 91 |
1
1. getFooterParts : negated conditional → KILLED |
if (hfp.getDefaultFooter() != null) set.add(hfp.getDefaultFooter()); |
| 92 |
1
1. getFooterParts : negated conditional → KILLED |
if (hfp.getEvenFooter() != null) set.add(hfp.getEvenFooter()); |
| 93 | } | |
| 94 | } | |
| 95 |
1
1. getFooterParts : replaced return value with Stream.empty for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::getFooterParts → SURVIVED |
return set.stream(); |
| 96 | } | |
| 97 | ||
| 98 | private static Optional<AsciiDocModel.InlineImage> extractGraphic(Graphic graphic) { | |
| 99 |
1
1. extractGraphic : negated conditional → NO_COVERAGE |
if (graphic.getGraphicData() == null) return Optional.empty(); |
| 100 | for (Object o : graphic.getGraphicData() | |
| 101 | .getAny()) { | |
| 102 | Object val = unwrap(o); | |
| 103 | // Handling WML textboxes (Wordprocessing Shape) | |
| 104 |
1
1. extractGraphic : negated conditional → NO_COVERAGE |
if (val instanceof Pic pic) { |
| 105 | var inlineImage = getInlineImage(pic); | |
| 106 |
1
1. extractGraphic : replaced return value with Optional.empty for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::extractGraphic → NO_COVERAGE |
return Optional.of(inlineImage); |
| 107 | } | |
| 108 | } | |
| 109 | return Optional.empty(); | |
| 110 | } | |
| 111 | ||
| 112 | private static AsciiDocModel.InlineImage getInlineImage(Pic pic) { | |
| 113 | var blipFill = pic.getBlipFill(); | |
| 114 | var blip = blipFill.getBlip(); | |
| 115 | var ctShapeProperties = pic.getSpPr(); | |
| 116 | var ctShapePropertiesXfrm = ctShapeProperties.getXfrm(); | |
| 117 | var ctShapePropertiesXfrmExt = ctShapePropertiesXfrm.getExt(); | |
| 118 | var cx = ctShapePropertiesXfrmExt.getCx(); | |
| 119 | var cy = ctShapePropertiesXfrmExt.getCy(); | |
| 120 | var embed = ofNullable(blip.getExtLst()).stream() | |
| 121 | .map(CTOfficeArtExtensionList::getExt) | |
| 122 | .flatMap(List::stream) | |
| 123 |
2
1. lambda$getInlineImage$0 : replaced boolean return with false for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$getInlineImage$0 → NO_COVERAGE 2. lambda$getInlineImage$0 : replaced boolean return with true for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$getInlineImage$0 → NO_COVERAGE |
.filter(e -> Objects.equals(e.getUri(), SVG_EXTENSION)) |
| 124 |
1
1. lambda$getInlineImage$1 : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$getInlineImage$1 → NO_COVERAGE |
.map(e -> (JAXBElement<?>) e.getAny()) |
| 125 |
1
1. lambda$getInlineImage$2 : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$getInlineImage$2 → NO_COVERAGE |
.map(jaxbElement -> (CTSVGBlip) jaxbElement.getValue()) |
| 126 | .map(CTSVGBlip::getEmbed) | |
| 127 | .findFirst() | |
| 128 | .orElse(blip.getEmbed()); | |
| 129 | ||
| 130 | var map = Map.of("cx", String.valueOf(cx), "cy", String.valueOf(cy)); | |
| 131 |
1
1. getInlineImage : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::getInlineImage → NO_COVERAGE |
return new AsciiDocModel.InlineImage(embed, map); |
| 132 | } | |
| 133 | ||
| 134 | private static Object unwrap(Object o) { | |
| 135 |
2
1. unwrap : negated conditional → KILLED 2. unwrap : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::unwrap → KILLED |
return (o instanceof JAXBElement<?> j) ? j.getValue() : o; |
| 136 | } | |
| 137 | ||
| 138 | private static Function<List<AsciiDocModel.Inline>, List<AsciiDocModel.Inline>> getWrapper(STVerticalAlignRun valign) { | |
| 139 |
1
1. getWrapper : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::getWrapper → NO_COVERAGE |
return switch (valign) { |
| 140 |
1
1. lambda$getWrapper$0 : replaced return value with Collections.emptyList for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$getWrapper$0 → NO_COVERAGE |
case BASELINE -> i -> i; |
| 141 |
1
1. lambda$getWrapper$1 : replaced return value with Collections.emptyList for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$getWrapper$1 → NO_COVERAGE |
case SUPERSCRIPT -> i -> List.of(new AsciiDocModel.Sup(i)); |
| 142 |
1
1. lambda$getWrapper$2 : replaced return value with Collections.emptyList for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$getWrapper$2 → NO_COVERAGE |
case SUBSCRIPT -> i -> List.of(new AsciiDocModel.Sub(i)); |
| 143 | }; | |
| 144 | } | |
| 145 | ||
| 146 | private static Function<List<AsciiDocModel.Inline>, List<AsciiDocModel.Inline>> boldwrapper(BooleanDefaultTrue w) { | |
| 147 |
2
1. lambda$boldwrapper$0 : replaced return value with Collections.emptyList for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$boldwrapper$0 → NO_COVERAGE 2. boldwrapper : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::boldwrapper → NO_COVERAGE |
return is -> List.of(new AsciiDocModel.Bold(is)); |
| 148 | } | |
| 149 | ||
| 150 | private static Function<List<AsciiDocModel.Inline>, List<AsciiDocModel.Inline>> italicwrapper(BooleanDefaultTrue booleanDefaultTrue) { | |
| 151 |
2
1. lambda$italicwrapper$0 : replaced return value with Collections.emptyList for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$italicwrapper$0 → NO_COVERAGE 2. italicwrapper : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::italicwrapper → NO_COVERAGE |
return is -> List.of(new AsciiDocModel.Italic(is)); |
| 152 | } | |
| 153 | ||
| 154 | private static Function<List<AsciiDocModel.Inline>, List<AsciiDocModel.Inline>> styledwrapper(String s) { | |
| 155 |
2
1. styledwrapper : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::styledwrapper → NO_COVERAGE 2. lambda$styledwrapper$0 : replaced return value with Collections.emptyList for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$styledwrapper$0 → NO_COVERAGE |
return is -> List.of(new AsciiDocModel.Styled(s, is)); |
| 156 | } | |
| 157 | ||
| 158 | private List<AsciiDocModel.Inline> toInlines(ContentAccessor accessor, BreakRecorder breakRecorder) { | |
| 159 | var inlines = new ArrayList<AsciiDocModel.Inline>(); | |
| 160 | for (Object o : accessor.getContent()) { | |
| 161 | Object val = unwrap(o); | |
| 162 | switch (val) { | |
| 163 | case R r -> inlines.addAll(getInlines(r, breakRecorder)); | |
| 164 | case ProofErr _ -> {/* NOOP */} | |
| 165 |
1
1. toInlines : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc$CommentRecorder::open → NO_COVERAGE |
case CommentRangeStart crs -> commentRecorder.open(crs.getId(), blocks.size(), 0); |
| 166 |
1
1. toInlines : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc$CommentRecorder::close → NO_COVERAGE |
case CommentRangeEnd cre -> commentRecorder.close(cre.getId(), blocks.size(), 0); |
| 167 | case SdtRun sdtRun -> { | |
| 168 | List<String> list = new ArrayList<>(); | |
| 169 | var id = ofNullable(sdtRun.getSdtPr()).map(SdtPr::getId) | |
| 170 | .map(Id::getVal) | |
| 171 | .map(BigInteger::intValueExact) | |
| 172 | .map(Integer::toHexString) | |
| 173 | .orElse(""); | |
| 174 | ||
| 175 | ofNullable(sdtRun.getSdtPr()).map(SdtPr::getTag) | |
| 176 | .map(Tag::getVal) | |
| 177 |
1
1. lambda$toInlines$0 : replaced return value with "" for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$toInlines$0 → NO_COVERAGE |
.map(s -> "tag=" + s) |
| 178 |
1
1. toInlines : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
.ifPresent(list::add); |
| 179 | list.add(toInlines(sdtRun.getSdtContent()).stream() | |
| 180 | .map(AsciiDocModel.Inline::text) | |
| 181 | .collect(Collectors.joining())); | |
| 182 | inlines.add(new AsciiDocModel.InlineMacro("form", id, list)); | |
| 183 | } | |
| 184 | case CTSmartTagRun tag -> { | |
| 185 | var list = new ArrayList<String>(); | |
| 186 | list.add("start"); | |
| 187 |
1
1. toInlines : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(tag.getElement()).ifPresent(e -> list.add("element=" + e)); |
| 188 | ofNullable(tag.getSmartTagPr()).stream() | |
| 189 | .map(CTSmartTagPr::getAttr) | |
| 190 | .flatMap(Collection::stream) | |
| 191 |
1
1. toInlines : removed call to java/util/stream/Stream::forEach → NO_COVERAGE |
.forEach(a -> list.add("%s=%s".formatted(a.getName(), a.getVal()))); |
| 192 | inlines.add(new AsciiDocModel.InlineMacro("tag", "", list)); | |
| 193 | inlines.addAll(toInlines(tag)); | |
| 194 | inlines.add(new AsciiDocModel.InlineMacro("tag", "", List.of("end"))); | |
| 195 | } | |
| 196 | case P.Hyperlink hyperlink -> inlines.addAll(toInlines(hyperlink)); | |
| 197 | default -> log.debug("Unexpected inline: {}", val); | |
| 198 | } | |
| 199 | } | |
| 200 |
1
1. toInlines : replaced return value with Collections.emptyList for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::toInlines → KILLED |
return List.copyOf(inlines); |
| 201 | } | |
| 202 | ||
| 203 | private List<AsciiDocModel.Inline> getInlines(R r, BreakRecorder breakRecorder) { | |
| 204 | var runInlines = extractInlines(r, breakRecorder); | |
| 205 | List<AsciiDocModel.Inline> styled = runInlines; | |
| 206 |
1
1. getInlines : negated conditional → SURVIVED |
if (!runInlines.isEmpty()) styled = significantPr(r.getRPr()).apply(runInlines); |
| 207 |
1
1. getInlines : replaced return value with Collections.emptyList for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::getInlines → KILLED |
return styled; |
| 208 | } | |
| 209 | ||
| 210 | private List<AsciiDocModel.Inline> toInlines(ContentAccessor accessor) { | |
| 211 |
1
1. toInlines : replaced return value with Collections.emptyList for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::toInlines → NO_COVERAGE |
return toInlines(accessor, new BreakRecorder()); |
| 212 | } | |
| 213 | ||
| 214 | private List<AsciiDocModel.Inline> extractInlines(ContentAccessor r, BreakRecorder brecorder) { | |
| 215 | var inlines = new ArrayList<AsciiDocModel.Inline>(); | |
| 216 | var content = r.getContent(); | |
| 217 | var iterator = content.iterator(); | |
| 218 | var sb = new StringBuilder(); | |
| 219 |
1
1. extractInlines : negated conditional → KILLED |
while (iterator.hasNext()) { |
| 220 | var rc = unwrap(iterator.next()); | |
| 221 | switch (rc) { | |
| 222 | case Text t -> sb.append(t.getValue()); | |
| 223 |
1
1. extractInlines : negated conditional → NO_COVERAGE |
case Br br when br.getType() == null -> sb.append(" +\n"); |
| 224 |
1
1. extractInlines : negated conditional → NO_COVERAGE |
case Br br when br.getType() == STBrType.TEXT_WRAPPING -> sb.append(" +\n"); |
| 225 |
2
1. extractInlines : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc$BreakRecorder::set → NO_COVERAGE 2. extractInlines : negated conditional → NO_COVERAGE |
case Br br when br.getType() == STBrType.COLUMN -> brecorder.set(); |
| 226 |
2
1. extractInlines : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc$BreakRecorder::set → NO_COVERAGE 2. extractInlines : negated conditional → NO_COVERAGE |
case Br br when br.getType() == STBrType.PAGE -> brecorder.set(); |
| 227 | case R.Tab _ -> sb.append("\t"); | |
| 228 | case CTFtnEdnRef n -> sb.append("footnote:%s[]".formatted(n.getId())); | |
| 229 |
1
1. extractInlines : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc$CommentRecorder::open → NO_COVERAGE |
case CommentRangeStart crs -> commentRecorder.open(crs.getId(), blocks.size(), inlines.size()); |
| 230 |
1
1. extractInlines : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc$CommentRecorder::close → NO_COVERAGE |
case CommentRangeEnd cre -> commentRecorder.close(cre.getId(), blocks.size(), inlines.size()); |
| 231 | case Pict pict -> { | |
| 232 |
1
1. extractInlines : negated conditional → NO_COVERAGE |
if (!sb.isEmpty()) { |
| 233 | inlines.add(new AsciiDocModel.Text(sb.toString())); | |
| 234 | sb = new StringBuilder(); | |
| 235 | } | |
| 236 | StringBuilder sb1 = new StringBuilder(); | |
| 237 | for (Object pO : pict.getAnyAndAny()) { | |
| 238 | Object pV = unwrap(pO); | |
| 239 |
1
1. extractInlines : negated conditional → NO_COVERAGE |
if (pV instanceof CTTextbox t) { |
| 240 | var txbxContent = t.getTxbxContent(); | |
| 241 | var toAsciiDoc = new DocxToAsciiDoc(wordprocessingMLPackage); | |
| 242 | var docModel = toAsciiDoc.apply(txbxContent); | |
| 243 | var compileToText = AsciiDocCompiler.toAsciidoc(docModel); | |
| 244 | var trimmed = compileToText.trim(); | |
| 245 | sb1.append(trimmed); | |
| 246 | } | |
| 247 | } | |
| 248 | sb.append(sb1); | |
| 249 | } | |
| 250 | case Drawing drawing -> { | |
| 251 |
1
1. extractInlines : negated conditional → NO_COVERAGE |
if (!sb.isEmpty()) { |
| 252 | inlines.add(new AsciiDocModel.Text(sb.toString())); | |
| 253 | sb = new StringBuilder(); | |
| 254 | } | |
| 255 | for (Object dO : drawing.getAnchorOrInline()) { | |
| 256 | Object dV = unwrap(dO); | |
| 257 | switch (dV) { | |
| 258 |
1
1. extractInlines : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
case Inline inline -> extractGraphic(inline.getGraphic()).ifPresent(inlines::add); |
| 259 |
1
1. extractInlines : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
case Anchor anchor -> extractGraphic(anchor.getGraphic()).ifPresent(inlines::add); |
| 260 | default -> { /* DO NOTHING */ } | |
| 261 | } | |
| 262 | } | |
| 263 | } | |
| 264 | default -> { /* DO NOTHING */ } | |
| 265 | } | |
| 266 | } | |
| 267 |
1
1. extractInlines : negated conditional → KILLED |
if (!sb.isEmpty()) { |
| 268 | inlines.add(new AsciiDocModel.Text(sb.toString())); | |
| 269 | } | |
| 270 |
1
1. extractInlines : replaced return value with Collections.emptyList for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::extractInlines → KILLED |
return inlines; |
| 271 | } | |
| 272 | ||
| 273 | private AsciiDocModel apply(ContentAccessor accessor) { | |
| 274 |
1
1. apply : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc::readBlocks → KILLED |
readBlocks(accessor); |
| 275 |
1
1. apply : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::apply → KILLED |
return of(blocks.blocks); |
| 276 | } | |
| 277 | ||
| 278 | private Function<List<AsciiDocModel.Inline>, List<AsciiDocModel.Inline>> significantPr(@Nullable RPr rPr) { | |
| 279 |
2
1. significantPr : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::significantPr → NO_COVERAGE 2. significantPr : negated conditional → SURVIVED |
if (rPr == null) return Function.identity(); |
| 280 | ||
| 281 | List<Function<List<AsciiDocModel.Inline>, List<AsciiDocModel.Inline>>> wrappers = new ArrayList<>(); | |
| 282 | ofNullable(rPr.getVertAlign()).map(CTVerticalAlignRun::getVal) | |
| 283 | .map(DocxToAsciiDoc::getWrapper) | |
| 284 |
1
1. significantPr : removed call to java/util/Optional::ifPresent → SURVIVED |
.ifPresent(wrappers::add); |
| 285 | ||
| 286 | ofNullable(rPr.getB()).filter(BooleanDefaultTrue::isVal) | |
| 287 | .map(DocxToAsciiDoc::boldwrapper) | |
| 288 |
1
1. significantPr : removed call to java/util/Optional::ifPresent → SURVIVED |
.ifPresent(wrappers::add); |
| 289 | ||
| 290 | ofNullable(rPr.getI()).filter(BooleanDefaultTrue::isVal) | |
| 291 | .map(DocxToAsciiDoc::italicwrapper) | |
| 292 |
1
1. significantPr : removed call to java/util/Optional::ifPresent → SURVIVED |
.ifPresent(wrappers::add); |
| 293 | ||
| 294 | ofNullable(rPr.getU()).map(U::getVal) | |
| 295 |
1
1. lambda$significantPr$0 : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$significantPr$0 → NO_COVERAGE |
.map(u -> DocxToAsciiDoc.styledwrapper("u_" + u.value())) |
| 296 |
1
1. significantPr : removed call to java/util/Optional::ifPresent → SURVIVED |
.ifPresent(wrappers::add); |
| 297 | ||
| 298 |
1
1. lambda$significantPr$1 : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$significantPr$1 → NO_COVERAGE |
ofNullable(rPr.getStrike()).map(_ -> DocxToAsciiDoc.styledwrapper("strike")) |
| 299 |
1
1. significantPr : removed call to java/util/Optional::ifPresent → SURVIVED |
.ifPresent(wrappers::add); |
| 300 | ||
| 301 |
1
1. lambda$significantPr$2 : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$significantPr$2 → NO_COVERAGE |
ofNullable(rPr.getHighlight()).map(h -> DocxToAsciiDoc.styledwrapper("highlight_" + h.getVal())) |
| 302 |
1
1. significantPr : removed call to java/util/Optional::ifPresent → SURVIVED |
.ifPresent(wrappers::add); |
| 303 | ||
| 304 |
1
1. lambda$significantPr$3 : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$significantPr$3 → NO_COVERAGE |
ofNullable(rPr.getColor()).map(c -> DocxToAsciiDoc.styledwrapper("color_" + c.getVal())) |
| 305 |
1
1. significantPr : removed call to java/util/Optional::ifPresent → SURVIVED |
.ifPresent(wrappers::add); |
| 306 | ||
| 307 |
1
1. lambda$significantPr$4 : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$significantPr$4 → NO_COVERAGE |
ofNullable(rPr.getRStyle()).map(s -> DocxToAsciiDoc.styledwrapper("rStyle_" + s.getVal())) |
| 308 |
1
1. significantPr : removed call to java/util/Optional::ifPresent → SURVIVED |
.ifPresent(wrappers::add); |
| 309 | ||
| 310 |
1
1. significantPr : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::significantPr → KILLED |
return wrappers.stream() |
| 311 | .reduce(Function::andThen) | |
| 312 | .orElse(Function.identity()); | |
| 313 | } | |
| 314 | ||
| 315 | private void readBlocks(ContentAccessor accessor) { | |
| 316 | for (Object o : accessor.getContent()) { | |
| 317 | Object val = unwrap(o); | |
| 318 | switch (val) { | |
| 319 |
1
1. readBlocks : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc$CommentRecorder::open → NO_COVERAGE |
case CommentRangeStart crs -> commentRecorder.open(crs.getId(), blocks.size(), 0); |
| 320 |
1
1. readBlocks : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc$CommentRecorder::close → NO_COVERAGE |
case CommentRangeEnd cre -> commentRecorder.close(cre.getId(), blocks.size(), 0); |
| 321 | case P p -> { | |
| 322 | var headerLevel = getHeaderLevel(p); | |
| 323 | var breakRecorder = new BreakRecorder(); | |
| 324 | ||
| 325 | ofNullable(p.getPPr()).map(PPr::getRPr) | |
| 326 | .flatMap(this::stringified) | |
| 327 |
2
1. lambda$readBlocks$0 : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc$BlockRecorder::add → NO_COVERAGE 2. readBlocks : removed call to java/util/Optional::ifPresent → SURVIVED |
.ifPresent(pr -> blocks.add(new AsciiDocModel.CommentLine(pr))); |
| 328 | ||
| 329 | var style = style(p).stream() | |
| 330 | .toList(); | |
| 331 | ||
| 332 |
1
1. readBlocks : negated conditional → KILLED |
if (headerLevel.isPresent()) |
| 333 |
1
1. readBlocks : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc$BlockRecorder::add → NO_COVERAGE |
blocks.add(new AsciiDocModel.Heading(style, headerLevel.get(), toInlines(p, breakRecorder))); |
| 334 |
1
1. readBlocks : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc$BlockRecorder::add → KILLED |
else blocks.add(new AsciiDocModel.Paragraph(style, toInlines(p, breakRecorder))); |
| 335 | ||
| 336 | ofNullable(p.getPPr()).map(PPr::getSectPr) | |
| 337 | .flatMap(this::stringified) | |
| 338 |
2
1. readBlocks : removed call to java/util/Optional::ifPresent → SURVIVED 2. lambda$readBlocks$1 : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc$BlockRecorder::add → NO_COVERAGE |
.ifPresent(s -> blocks.add(new AsciiDocModel.CommentLine(s))); |
| 339 | ||
| 340 |
2
1. readBlocks : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc$BlockRecorder::add → NO_COVERAGE 2. readBlocks : negated conditional → KILLED |
if (breakRecorder.isSet()) blocks.add(new AsciiDocModel.Break()); |
| 341 | } | |
| 342 |
1
1. readBlocks : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc$BlockRecorder::add → KILLED |
case Tbl tbl -> blocks.add(toTableBlock(tbl)); |
| 343 |
1
1. readBlocks : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc$BlockRecorder::add → NO_COVERAGE |
case SdtBlock sdtBlock -> blocks.add(toSdtBlock(sdtBlock)); |
| 344 | default -> log.debug("Unexpected block: {}", val); | |
| 345 | } | |
| 346 | } | |
| 347 | } | |
| 348 | ||
| 349 | private AsciiDocModel.Block toSdtBlock(SdtBlock sdtBlock) { | |
| 350 | var form = "form"; | |
| 351 | var id = ofNullable(sdtBlock.getSdtPr()).map(SdtPr::getId) | |
| 352 | .map(Id::getVal) | |
| 353 | .map(BigInteger::intValueExact) | |
| 354 | .map(Integer::toHexString); | |
| 355 | var tag = ofNullable(sdtBlock.getSdtPr()).map(SdtPr::getTag) | |
| 356 | .map(Tag::getVal); | |
| 357 | var header = new ArrayList<String>(); | |
| 358 | header.add(form); | |
| 359 |
1
1. toSdtBlock : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
id.ifPresent(e -> header.add("id=" + e)); |
| 360 |
1
1. toSdtBlock : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
tag.ifPresent(e -> header.add("tag=" + e)); |
| 361 | var toAsciiDoc = new DocxToAsciiDoc(wordprocessingMLPackage); | |
| 362 |
1
1. lambda$toSdtBlock$2 : replaced return value with Collections.emptyList for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$toSdtBlock$2 → NO_COVERAGE |
var docModel = toAsciiDoc.apply(() -> sdtBlock.getSdtContent() |
| 363 | .getContent()); | |
| 364 |
1
1. toSdtBlock : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::toSdtBlock → NO_COVERAGE |
return new AsciiDocModel.OpenBlock(header, docModel.getBlocks()); |
| 365 | } | |
| 366 | ||
| 367 | private Optional<String> stringified(ParaRPr paraRPr) { | |
| 368 | var map = new TreeMap<String, Object>(); | |
| 369 |
1
1. stringified : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(paraRPr.getHighlight()).ifPresent(h -> map.put("highlight", h.getVal())); |
| 370 |
1
1. stringified : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(paraRPr.getColor()).ifPresent(c -> map.put("color", c.getVal())); |
| 371 |
1
1. stringified : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(paraRPr.getRFonts()).ifPresent(r -> { |
| 372 | var rFontMap = new TreeMap<String, Object>(); | |
| 373 |
1
1. lambda$stringified$2 : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(r.getAscii()).ifPresent(a -> rFontMap.put("ascii", a)); |
| 374 |
1
1. lambda$stringified$2 : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(r.getHAnsi()).ifPresent(h -> rFontMap.put("hAnsi", h)); |
| 375 |
1
1. lambda$stringified$2 : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(r.getEastAsia()).ifPresent(e -> rFontMap.put("eastAsia", e)); |
| 376 |
1
1. lambda$stringified$2 : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(r.getCs()).ifPresent(c -> rFontMap.put("cs", c)); |
| 377 |
1
1. lambda$stringified$2 : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(r.getAsciiTheme()).ifPresent(a -> rFontMap.put("asciiTheme", a.value())); |
| 378 |
1
1. lambda$stringified$2 : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(r.getHAnsiTheme()).ifPresent(h -> rFontMap.put("hAnsi", h.value())); |
| 379 |
1
1. lambda$stringified$2 : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(r.getEastAsiaTheme()).ifPresent(e -> rFontMap.put("eastAsia", e.value())); |
| 380 |
1
1. lambda$stringified$2 : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(r.getCstheme()).ifPresent(c -> rFontMap.put("cs", c.value())); |
| 381 |
1
1. lambda$stringified$2 : negated conditional → NO_COVERAGE |
if (!rFontMap.isEmpty()) map.put("rFonts", rFontMap); |
| 382 | }); | |
| 383 |
1
1. stringified : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(paraRPr.getSz()).ifPresent(s -> map.put("sz", s.getVal())); |
| 384 |
1
1. stringified : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(paraRPr.getSzCs()).ifPresent(s -> map.put("szCs", s.getVal())); |
| 385 |
1
1. stringified : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(paraRPr.getU()).ifPresent(u -> map.put("u", u.getVal())); |
| 386 |
1
1. stringified : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(paraRPr.getHighlight()).ifPresent(h -> map.put("highlight", h.getVal())); |
| 387 |
1
1. stringified : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(paraRPr.getI()).ifPresent(i -> map.put("i", i.isVal())); |
| 388 |
2
1. stringified : negated conditional → NO_COVERAGE 2. stringified : replaced return value with Optional.empty for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::stringified → NO_COVERAGE |
return map.isEmpty() ? Optional.empty() : Optional.of("runPr %s".formatted(map)); |
| 389 | } | |
| 390 | ||
| 391 | private Optional<String> stringified(SectPr sectPr) { | |
| 392 | var map = new TreeMap<String, Object>(); | |
| 393 |
1
1. stringified : removed call to java/util/Optional::ifPresent → SURVIVED |
ofNullable(sectPr.getDocGrid()).ifPresent(d -> { |
| 394 | var dgmap = new TreeMap<String, Object>(); | |
| 395 |
1
1. lambda$stringified$16 : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(d.getLinePitch()).ifPresent(l -> dgmap.put("linePitch", l)); |
| 396 |
1
1. lambda$stringified$16 : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(d.getCharSpace()).ifPresent(c -> dgmap.put("charSpace", c)); |
| 397 |
1
1. lambda$stringified$16 : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(d.getType()).ifPresent(t -> dgmap.put("type", t.value())); |
| 398 | map.put("docGrid", dgmap); | |
| 399 | }); | |
| 400 |
1
1. stringified : removed call to java/util/Optional::ifPresent → KILLED |
ofNullable(sectPr.getPgMar()).ifPresent(p -> { |
| 401 | var pmmap = new TreeMap<String, Object>(); | |
| 402 |
2
1. lambda$stringified$21 : replaced boolean return with true for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$stringified$21 → SURVIVED 2. lambda$stringified$21 : negated conditional → KILLED |
ofNullable(p.getTop()).filter(t -> !BigInteger.ZERO.equals(t)) |
| 403 |
1
1. lambda$stringified$20 : removed call to java/util/Optional::ifPresent → KILLED |
.ifPresent(t -> pmmap.put("top", t)); |
| 404 |
2
1. lambda$stringified$23 : replaced boolean return with true for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$stringified$23 → SURVIVED 2. lambda$stringified$23 : negated conditional → KILLED |
ofNullable(p.getBottom()).filter(t -> !BigInteger.ZERO.equals(t)) |
| 405 |
1
1. lambda$stringified$20 : removed call to java/util/Optional::ifPresent → KILLED |
.ifPresent(b -> pmmap.put("bottom", b)); |
| 406 |
2
1. lambda$stringified$25 : replaced boolean return with true for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$stringified$25 → SURVIVED 2. lambda$stringified$25 : negated conditional → KILLED |
ofNullable(p.getLeft()).filter(t -> !BigInteger.ZERO.equals(t)) |
| 407 |
1
1. lambda$stringified$20 : removed call to java/util/Optional::ifPresent → KILLED |
.ifPresent(l -> pmmap.put("left", l)); |
| 408 |
2
1. lambda$stringified$27 : replaced boolean return with true for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$stringified$27 → SURVIVED 2. lambda$stringified$27 : negated conditional → KILLED |
ofNullable(p.getRight()).filter(t -> !BigInteger.ZERO.equals(t)) |
| 409 |
1
1. lambda$stringified$20 : removed call to java/util/Optional::ifPresent → KILLED |
.ifPresent(r -> pmmap.put("right", r)); |
| 410 |
2
1. lambda$stringified$29 : replaced boolean return with true for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$stringified$29 → NO_COVERAGE 2. lambda$stringified$29 : negated conditional → NO_COVERAGE |
ofNullable(p.getHeader()).filter(t -> !BigInteger.ZERO.equals(t)) |
| 411 |
1
1. lambda$stringified$20 : removed call to java/util/Optional::ifPresent → SURVIVED |
.ifPresent(h -> pmmap.put("header", h)); |
| 412 |
2
1. lambda$stringified$31 : negated conditional → NO_COVERAGE 2. lambda$stringified$31 : replaced boolean return with true for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$stringified$31 → NO_COVERAGE |
ofNullable(p.getFooter()).filter(t -> !BigInteger.ZERO.equals(t)) |
| 413 |
1
1. lambda$stringified$20 : removed call to java/util/Optional::ifPresent → SURVIVED |
.ifPresent(f -> pmmap.put("footer", f)); |
| 414 |
2
1. lambda$stringified$33 : replaced boolean return with true for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$stringified$33 → NO_COVERAGE 2. lambda$stringified$33 : negated conditional → NO_COVERAGE |
ofNullable(p.getGutter()).filter(t -> !BigInteger.ZERO.equals(t)) |
| 415 |
1
1. lambda$stringified$20 : removed call to java/util/Optional::ifPresent → SURVIVED |
.ifPresent(g -> pmmap.put("gutter", g)); |
| 416 | map.put("pgMar", pmmap); | |
| 417 | }); | |
| 418 |
1
1. stringified : removed call to java/util/Optional::ifPresent → KILLED |
ofNullable(sectPr.getPgSz()).ifPresent(p -> { |
| 419 | var psmap = new TreeMap<String, Object>(); | |
| 420 |
2
1. lambda$stringified$36 : replaced boolean return with true for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$stringified$36 → SURVIVED 2. lambda$stringified$36 : negated conditional → KILLED |
ofNullable(p.getW()).filter(t -> !BigInteger.ZERO.equals(t)) |
| 421 |
1
1. lambda$stringified$35 : removed call to java/util/Optional::ifPresent → KILLED |
.ifPresent(w -> psmap.put("w", w)); |
| 422 |
2
1. lambda$stringified$38 : replaced boolean return with true for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$stringified$38 → SURVIVED 2. lambda$stringified$38 : negated conditional → KILLED |
ofNullable(p.getH()).filter(t -> !BigInteger.ZERO.equals(t)) |
| 423 |
1
1. lambda$stringified$35 : removed call to java/util/Optional::ifPresent → KILLED |
.ifPresent(h -> psmap.put("h", h)); |
| 424 |
1
1. lambda$stringified$35 : removed call to java/util/Optional::ifPresent → SURVIVED |
ofNullable(p.getOrient()).ifPresent(o -> psmap.put("orient", o.value())); |
| 425 |
2
1. lambda$stringified$41 : replaced boolean return with true for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$stringified$41 → SURVIVED 2. lambda$stringified$41 : negated conditional → KILLED |
ofNullable(p.getCode()).filter(t -> !BigInteger.ZERO.equals(t)) |
| 426 |
1
1. lambda$stringified$35 : removed call to java/util/Optional::ifPresent → KILLED |
.ifPresent(c -> psmap.put("code", c)); |
| 427 | map.put("pgSz", psmap); | |
| 428 | }); | |
| 429 |
1
1. stringified : removed call to java/util/Optional::ifPresent → SURVIVED |
ofNullable(sectPr.getPgBorders()).ifPresent(p -> map.put("pgBorders", p)); |
| 430 |
1
1. stringified : removed call to java/util/Optional::ifPresent → SURVIVED |
ofNullable(sectPr.getBidi()).ifPresent(b -> map.put("bidi", b.isVal())); |
| 431 |
1
1. stringified : removed call to java/util/Optional::ifPresent → SURVIVED |
ofNullable(sectPr.getCols()).ifPresent(c -> { |
| 432 | var colMap = new TreeMap<String, Object>(); | |
| 433 |
2
1. lambda$stringified$46 : replaced boolean return with true for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$stringified$46 → NO_COVERAGE 2. lambda$stringified$46 : negated conditional → NO_COVERAGE |
ofNullable(c.getNum()).filter(t -> !BigInteger.ZERO.equals(t)) |
| 434 |
1
1. lambda$stringified$45 : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
.ifPresent(n -> map.put("num", n)); |
| 435 |
2
1. lambda$stringified$48 : negated conditional → NO_COVERAGE 2. lambda$stringified$48 : replaced boolean return with true for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$stringified$48 → NO_COVERAGE |
ofNullable(c.getSpace()).filter(t -> !BigInteger.ZERO.equals(t)) |
| 436 |
1
1. lambda$stringified$45 : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
.ifPresent(s -> map.put("space", s)); |
| 437 |
1
1. lambda$stringified$45 : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(c.getCol()).ifPresent(c1 -> { |
| 438 | var list = c1.stream() | |
| 439 | .map(coli -> { | |
| 440 | var colim = new TreeMap<String, Object>(); | |
| 441 |
1
1. lambda$stringified$51 : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(coli.getSpace()).ifPresent(s -> colim.put("space", s)); |
| 442 |
1
1. lambda$stringified$51 : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
ofNullable(coli.getW()).ifPresent(w -> colim.put("w", w)); |
| 443 |
1
1. lambda$stringified$51 : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$stringified$51 → NO_COVERAGE |
return colim; |
| 444 | }) | |
| 445 | .toList(); | |
| 446 |
1
1. lambda$stringified$50 : negated conditional → NO_COVERAGE |
if (!list.isEmpty()) colMap.put("col", list); |
| 447 | }); | |
| 448 |
1
1. lambda$stringified$45 : negated conditional → NO_COVERAGE |
if (!colMap.isEmpty()) map.put("cols", colMap); |
| 449 | }); | |
| 450 |
1
1. stringified : removed call to java/util/Optional::ifPresent → SURVIVED |
ofNullable(sectPr.getType()).ifPresent(t -> map.put("type", t)); |
| 451 |
2
1. stringified : negated conditional → KILLED 2. stringified : replaced return value with Optional.empty for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::stringified → KILLED |
return map.isEmpty() ? Optional.empty() : Optional.of("section %s".formatted(map)); |
| 452 | } | |
| 453 | ||
| 454 | private Optional<String> style(P p) { | |
| 455 |
1
1. style : replaced return value with Optional.empty for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::style → SURVIVED |
return ofNullable(p.getPPr()).map(PPr::getPStyle) |
| 456 | .map(PStyle::getVal) | |
| 457 | .map(styleDefinitionsPart::getNameForStyleID); | |
| 458 | } | |
| 459 | ||
| 460 | private Optional<Integer> getHeaderLevel(P p) { | |
| 461 |
1
1. getHeaderLevel : negated conditional → KILLED |
if (p.getPPr() == null || p.getPPr() |
| 462 |
1
1. getHeaderLevel : negated conditional → NO_COVERAGE |
.getPStyle() == null) return Optional.empty(); |
| 463 | var styleId = p.getPPr() | |
| 464 | .getPStyle() | |
| 465 | .getVal(); | |
| 466 | var styleName = styleDefinitionsPart.getNameForStyleID(styleId); | |
| 467 |
1
1. getHeaderLevel : negated conditional → NO_COVERAGE |
if (styleName == null) styleName = styleId; |
| 468 | ||
| 469 |
2
1. getHeaderLevel : negated conditional → NO_COVERAGE 2. getHeaderLevel : negated conditional → NO_COVERAGE |
if (styleName.equalsIgnoreCase("Title") || styleName.equalsIgnoreCase("Titre")) { |
| 470 |
1
1. getHeaderLevel : replaced return value with Optional.empty for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::getHeaderLevel → NO_COVERAGE |
return Optional.of(1); |
| 471 | } | |
| 472 | if (styleName.toLowerCase() | |
| 473 |
1
1. getHeaderLevel : negated conditional → NO_COVERAGE |
.startsWith("heading") || styleName.toLowerCase() |
| 474 |
1
1. getHeaderLevel : negated conditional → NO_COVERAGE |
.startsWith("titre")) { |
| 475 | String levelStr = styleName.replaceAll("\\D", ""); | |
| 476 |
1
1. getHeaderLevel : negated conditional → NO_COVERAGE |
if (!levelStr.isEmpty()) { |
| 477 |
2
1. getHeaderLevel : Replaced integer addition with subtraction → NO_COVERAGE 2. getHeaderLevel : replaced return value with Optional.empty for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::getHeaderLevel → NO_COVERAGE |
return Optional.of(Integer.parseInt(levelStr) + 1); |
| 478 | } | |
| 479 | } | |
| 480 | return Optional.empty(); | |
| 481 | } | |
| 482 | ||
| 483 | private AsciiDocModel.Table toTableBlock(Tbl tbl) { | |
| 484 | List<AsciiDocModel.Row> rows = new ArrayList<>(); | |
| 485 | for (Object trO : tbl.getContent()) { | |
| 486 | Object trV = unwrap(trO); | |
| 487 |
1
1. toTableBlock : negated conditional → KILLED |
if (!(trV instanceof Tr tr)) continue; |
| 488 | List<AsciiDocModel.Cell> cells = new ArrayList<>(); | |
| 489 | for (Object tcO : tr.getContent()) { | |
| 490 | Object tcV = unwrap(tcO); | |
| 491 |
1
1. toTableBlock : negated conditional → KILLED |
if (!(tcV instanceof Tc tc)) continue; |
| 492 | var toAsciiDoc = new DocxToAsciiDoc(wordprocessingMLPackage); | |
| 493 | List<AsciiDocModel.Block> cellBlocks = toAsciiDoc.apply(tc) | |
| 494 | .getBlocks(); | |
| 495 | Optional<String> ccnfStyle = Optional.empty(); | |
| 496 |
1
1. toTableBlock : negated conditional → KILLED |
if (tc.getTcPr() != null && tc.getTcPr() |
| 497 |
1
1. toTableBlock : negated conditional → NO_COVERAGE |
.getCnfStyle() != null) { |
| 498 | ccnfStyle = ofNullable(tc.getTcPr()).map(TcPrInner::getCnfStyle) | |
| 499 |
1
1. lambda$toTableBlock$0 : replaced return value with "" for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$toTableBlock$0 → NO_COVERAGE |
.map(s -> "style=" + Long.parseLong(s.getVal(), 2)); |
| 500 | ||
| 501 | } | |
| 502 | cells.add(new AsciiDocModel.Cell(cellBlocks, ccnfStyle)); | |
| 503 | } | |
| 504 | Optional<String> cnfStyle = Optional.empty(); | |
| 505 |
1
1. toTableBlock : negated conditional → KILLED |
if (tr.getTrPr() != null && tr.getTrPr() |
| 506 |
1
1. toTableBlock : negated conditional → NO_COVERAGE |
.getCnfStyleOrDivIdOrGridBefore() != null) { |
| 507 | cnfStyle = tr.getTrPr() | |
| 508 | .getCnfStyleOrDivIdOrGridBefore() | |
| 509 | .stream() | |
| 510 | .map(DocxToAsciiDoc::unwrap) | |
| 511 | .filter(CTCnf.class::isInstance) | |
| 512 | .map(CTCnf.class::cast) | |
| 513 | .findFirst() | |
| 514 |
1
1. lambda$toTableBlock$1 : replaced return value with "" for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::lambda$toTableBlock$1 → NO_COVERAGE |
.map(s -> "rowStyle=" + Long.parseLong(s.getVal(), 2)); |
| 515 | ||
| 516 | } | |
| 517 | rows.add(new AsciiDocModel.Row(cells, cnfStyle)); | |
| 518 | } | |
| 519 |
1
1. toTableBlock : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::toTableBlock → KILLED |
return new AsciiDocModel.Table(rows); |
| 520 | } | |
| 521 | ||
| 522 | @Override | |
| 523 | public AsciiDocModel apply(WordprocessingMLPackage pkg) { | |
| 524 | getHeaderParts(pkg).map(this::toHeaderBlock) | |
| 525 | .flatMap(Optional::stream) | |
| 526 |
1
1. apply : removed call to java/util/stream/Stream::forEach → SURVIVED |
.forEach(blocks::add); |
| 527 | var mdp = pkg.getMainDocumentPart(); | |
| 528 | ||
| 529 | { | |
| 530 | Document contents; | |
| 531 | try { | |
| 532 | contents = mdp.getContents(); | |
| 533 | } catch (Docx4JException e) { | |
| 534 | throw new RuntimeException(e); | |
| 535 | } | |
| 536 | var body = contents.getBody(); | |
| 537 |
1
1. apply : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc::readBlocks → KILLED |
readBlocks(body); |
| 538 |
1
1. apply : negated conditional → KILLED |
if (body.getSectPr() instanceof SectPr sectPr) |
| 539 |
2
1. apply : removed call to java/util/Optional::ifPresent → KILLED 2. lambda$apply$0 : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc$BlockRecorder::add → KILLED |
stringified(sectPr).ifPresent(s -> blocks.add(new AsciiDocModel.CommentLine(s))); |
| 540 | } | |
| 541 | ||
| 542 | try { | |
| 543 | var footnotesPart = mdp.getFootnotesPart(); | |
| 544 |
1
1. apply : negated conditional → KILLED |
if (footnotesPart != null) { |
| 545 | var contents = footnotesPart.getContents(); | |
| 546 | var footnote = contents.getFootnote(); | |
| 547 |
1
1. apply : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
toNoteBlock("footnotes", footnote).ifPresent(blocks::add); |
| 548 | } | |
| 549 | var endNotesPart = mdp.getEndNotesPart(); | |
| 550 |
1
1. apply : negated conditional → KILLED |
if (endNotesPart != null) { |
| 551 | var contents = endNotesPart.getContents(); | |
| 552 | var endnote = contents.getEndnote(); | |
| 553 |
1
1. apply : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
toNoteBlock("endnotes", endnote).ifPresent(blocks::add); |
| 554 | } | |
| 555 | } catch (Docx4JException e) { | |
| 556 | throw new RuntimeException(e); | |
| 557 | } | |
| 558 | getFooterParts(pkg).map(this::toFooterBlock) | |
| 559 | .flatMap(Optional::stream) | |
| 560 |
1
1. apply : removed call to java/util/stream/Stream::forEach → SURVIVED |
.forEach(blocks::add); |
| 561 | var list = new ArrayList<AsciiDocModel.Block>(); | |
| 562 | list.addAll(commentRecorder.all()); | |
| 563 | list.addAll(blocks.all()); | |
| 564 |
1
1. apply : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::apply → KILLED |
return of(list); |
| 565 | } | |
| 566 | ||
| 567 | private Optional<AsciiDocModel.Block> toFooterBlock(FooterPart footerPart) { | |
| 568 | var toAsciiDoc = new DocxToAsciiDoc(wordprocessingMLPackage); | |
| 569 | var extractedBlocks = toAsciiDoc.apply(footerPart) | |
| 570 | .getBlocks(); | |
| 571 |
2
1. toFooterBlock : replaced return value with Optional.empty for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::toFooterBlock → NO_COVERAGE 2. toFooterBlock : negated conditional → NO_COVERAGE |
return extractedBlocks.isEmpty() |
| 572 | ? Optional.empty() | |
| 573 | : Optional.of(new AsciiDocModel.OpenBlock(List.of("footer"), extractedBlocks)); | |
| 574 | ||
| 575 | } | |
| 576 | ||
| 577 | private Optional<AsciiDocModel.Block> toHeaderBlock(HeaderPart headerPart) { | |
| 578 | var toAsciiDoc = new DocxToAsciiDoc(wordprocessingMLPackage); | |
| 579 | var extractedBlocks = toAsciiDoc.apply(headerPart) | |
| 580 | .getBlocks(); | |
| 581 |
2
1. toHeaderBlock : replaced return value with Optional.empty for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::toHeaderBlock → NO_COVERAGE 2. toHeaderBlock : negated conditional → NO_COVERAGE |
return extractedBlocks.isEmpty() |
| 582 | ? Optional.empty() | |
| 583 | : Optional.of(new AsciiDocModel.OpenBlock(List.of("header"), extractedBlocks)); | |
| 584 | } | |
| 585 | ||
| 586 | private Optional<AsciiDocModel.Block> toNoteBlock(String role, List<CTFtnEdn> notes) { | |
| 587 | var content = new ArrayList<AsciiDocModel.Block>(); | |
| 588 | for (CTFtnEdn note : notes) { | |
| 589 | var noteType = note.getType(); | |
| 590 |
1
1. toNoteBlock : negated conditional → NO_COVERAGE |
if (noteType != null && List.of(STFtnEdn.SEPARATOR, STFtnEdn.CONTINUATION_SEPARATOR) |
| 591 |
1
1. toNoteBlock : negated conditional → NO_COVERAGE |
.contains(noteType)) continue; |
| 592 | var toAsciiDoc = new DocxToAsciiDoc(wordprocessingMLPackage); | |
| 593 | var extractedBlocks = toAsciiDoc.apply(note::getContent) | |
| 594 | .getBlocks(); | |
| 595 | content.add(new AsciiDocModel.Paragraph(List.of(new AsciiDocModel.Text("%s::".formatted(note.getId()))))); | |
| 596 | content.addAll(extractedBlocks); | |
| 597 | } | |
| 598 |
2
1. toNoteBlock : replaced return value with Optional.empty for pro/verron/officestamper/asciidoc/DocxToAsciiDoc::toNoteBlock → NO_COVERAGE 2. toNoteBlock : negated conditional → NO_COVERAGE |
return content.isEmpty() ? Optional.empty() : Optional.of(new AsciiDocModel.OpenBlock(List.of(role), content)); |
| 599 | } | |
| 600 | ||
| 601 | private static class BreakRecorder { | |
| 602 | private boolean set; | |
| 603 | ||
| 604 | public void set() { | |
| 605 | set = true; | |
| 606 | } | |
| 607 | ||
| 608 | public boolean isSet() { | |
| 609 |
2
1. isSet : replaced boolean return with false for pro/verron/officestamper/asciidoc/DocxToAsciiDoc$BreakRecorder::isSet → SURVIVED 2. isSet : replaced boolean return with true for pro/verron/officestamper/asciidoc/DocxToAsciiDoc$BreakRecorder::isSet → KILLED |
return set; |
| 610 | } | |
| 611 | } | |
| 612 | ||
| 613 | /// Maintains and organizes a collection of comments while facilitating | |
| 614 | /// the construction of structured output representations. | |
| 615 | /// | |
| 616 | /// Provides functionality to open and close comments using unique identifiers | |
| 617 | /// and convert comments into macro representations suitable for downstream | |
| 618 | /// processing. | |
| 619 | /// | |
| 620 | /// The class also ensures that comments are opened and closed in a well-formed | |
| 621 | /// manner, enforcing constraints while maintaining the internal structure. | |
| 622 | public static class CommentRecorder { | |
| 623 | private final Deque<CommentBuilder> comments; | |
| 624 | private final List<BigInteger> ids; | |
| 625 | private final Map<BigInteger, Comment> map; | |
| 626 | private final CommentsPart commentsPart; | |
| 627 | ||
| 628 | CommentRecorder(CommentsPart commentsPart) { | |
| 629 | this.commentsPart = commentsPart; | |
| 630 | comments = new ArrayDeque<>(); | |
| 631 | ids = new ArrayList<>(); | |
| 632 | map = new HashMap<>(); | |
| 633 | } | |
| 634 | ||
| 635 | /// Opens a new comment using the specified identifier and positional information. | |
| 636 | /// The comment is constructed using a [CommentBuilder] and stored internally. | |
| 637 | /// | |
| 638 | /// @param id the unique identifier for the comment as a [BigInteger] | |
| 639 | /// @param blockStart the starting block position for the comment as an integer | |
| 640 | /// @param lineStart the starting line position for the comment as an integer | |
| 641 | public void open(BigInteger id, int blockStart, int lineStart) { | |
| 642 | var builder = new CommentBuilder(id); | |
| 643 | builder.setBlockStart(blockStart); | |
| 644 | builder.setLineStart(lineStart); | |
| 645 |
1
1. open : removed call to java/util/Deque::addLast → NO_COVERAGE |
comments.addLast(builder); |
| 646 | ids.add(id); | |
| 647 | } | |
| 648 | ||
| 649 | /// Closes a comment identified by the provided ID and assigns the ending block | |
| 650 | /// and line positions for the comment being finalized. The comment is then | |
| 651 | /// stored internally for further processing. | |
| 652 | /// | |
| 653 | /// @param id the unique identifier of the comment as a [BigInteger] | |
| 654 | /// @param blockEnd the ending block position of the comment as an integer | |
| 655 | /// @param lineEnd the ending line position of the comment as an integer | |
| 656 | /// @throws IllegalStateException if the provided ID does not match the ID of | |
| 657 | /// the last opened comment | |
| 658 | public void close(BigInteger id, int blockEnd, int lineEnd) { | |
| 659 | var lastComment = comments.removeLast(); | |
| 660 | var lastCommentId = lastComment.getId(); | |
| 661 | var msg = "Closing comment %s but last comment open is %s".formatted(id, lastCommentId); | |
| 662 |
1
1. close : removed call to pro/verron/officestamper/asciidoc/DocxToAsciiDoc$CommentRecorder::assertThat → NO_COVERAGE |
assertThat(lastCommentId.equals(id), msg); |
| 663 | lastComment.setBlockEnd(blockEnd); | |
| 664 | lastComment.setLineEnd(lineEnd); | |
| 665 | map.put(id, lastComment.createComment()); | |
| 666 | } | |
| 667 | ||
| 668 | private void assertThat(boolean bool, String msg) { | |
| 669 |
1
1. assertThat : negated conditional → NO_COVERAGE |
if (!bool) throw new IllegalStateException(msg); |
| 670 | } | |
| 671 | ||
| 672 | /// Retrieves a collection of all MacroBlock representations for the stored comment IDs. | |
| 673 | /// | |
| 674 | /// The method maps the list of IDs through a series of operations to construct | |
| 675 | /// MacroBlock objects from the associated comments. | |
| 676 | /// | |
| 677 | /// @return a collection of MacroBlock objects corresponding to the stored comment IDs. | |
| 678 | public Collection<AsciiDocModel.MacroBlock> all() { | |
| 679 |
1
1. all : replaced return value with Collections.emptyList for pro/verron/officestamper/asciidoc/DocxToAsciiDoc$CommentRecorder::all → SURVIVED |
return ids.stream() |
| 680 | .map(map::get) | |
| 681 | .map(this::asBlock) | |
| 682 | .toList(); | |
| 683 | } | |
| 684 | ||
| 685 | private AsciiDocModel.MacroBlock asBlock(Comment comment) { | |
| 686 | var id = comment.id(); | |
| 687 | var idStr = String.valueOf(id); | |
| 688 | var blockStart = comment.blockStart(); | |
| 689 | var lineStart = comment.lineStart(); | |
| 690 | var blockEnd = comment.blockEnd(); | |
| 691 | var lineEnd = comment.lineEnd(); | |
| 692 | var commentMessage = extractComment(id); | |
| 693 | var startProp = "start=\"%d,%d\"".formatted(blockStart, lineStart); | |
| 694 | var endProp = "end=\"%d,%d\"".formatted(blockEnd, lineEnd); | |
| 695 | var valueProp = "value=\"%s\"".formatted(commentMessage); | |
| 696 | var list = List.of(startProp, endProp, valueProp); | |
| 697 |
1
1. asBlock : replaced return value with null for pro/verron/officestamper/asciidoc/DocxToAsciiDoc$CommentRecorder::asBlock → NO_COVERAGE |
return new AsciiDocModel.MacroBlock("comment", idStr, list); |
| 698 | } | |
| 699 | ||
| 700 | private String extractComment(BigInteger id) { | |
| 701 | try { | |
| 702 |
1
1. extractComment : replaced return value with "" for pro/verron/officestamper/asciidoc/DocxToAsciiDoc$CommentRecorder::extractComment → NO_COVERAGE |
return this.commentsPart.getContents() |
| 703 | .getComment() | |
| 704 | .stream() | |
| 705 |
2
1. lambda$extractComment$0 : replaced boolean return with true for pro/verron/officestamper/asciidoc/DocxToAsciiDoc$CommentRecorder::lambda$extractComment$0 → NO_COVERAGE 2. lambda$extractComment$0 : replaced boolean return with false for pro/verron/officestamper/asciidoc/DocxToAsciiDoc$CommentRecorder::lambda$extractComment$0 → NO_COVERAGE |
.filter(c -> Objects.equals(c.getId(), id)) |
| 706 | .findFirst() | |
| 707 | .map(this::str) | |
| 708 | .orElseThrow(); | |
| 709 | } catch (Docx4JException e) { | |
| 710 | throw new RuntimeException(e); | |
| 711 | } | |
| 712 | } | |
| 713 | ||
| 714 | private String str(Comments.Comment comment) { | |
| 715 | ||
| 716 | var first = (P) comment.getContent() | |
| 717 | .getFirst(); | |
| 718 |
1
1. str : replaced return value with "" for pro/verron/officestamper/asciidoc/DocxToAsciiDoc$CommentRecorder::str → NO_COVERAGE |
return TextUtils.getText(first); |
| 719 | } | |
| 720 | ||
| 721 | /// Represents a comment with positional information, identified by a unique ID. | |
| 722 | /// | |
| 723 | /// This class is an immutable record storing metadata about a comment, | |
| 724 | /// including its unique identifier, starting and ending block positions, | |
| 725 | /// as well as starting and ending line positions. | |
| 726 | /// | |
| 727 | /// Fields: | |
| 728 | /// - id: The unique identifier for the comment. | |
| 729 | /// - blockStart: The starting block position of the comment. | |
| 730 | /// - lineStart: The starting line position of the comment. | |
| 731 | /// - blockEnd: The ending block position of the comment. | |
| 732 | /// - lineEnd: The ending line position of the comment. | |
| 733 | public record Comment(BigInteger id, int blockStart, int lineStart, int blockEnd, int lineEnd) {} | |
| 734 | } | |
| 735 | ||
| 736 | private static class BlockRecorder { | |
| 737 | private final List<AsciiDocModel.Block> blocks = new ArrayList<>(); | |
| 738 | private int size = 0; | |
| 739 | ||
| 740 | public int size() { | |
| 741 |
1
1. size : replaced int return with 0 for pro/verron/officestamper/asciidoc/DocxToAsciiDoc$BlockRecorder::size → NO_COVERAGE |
return size; |
| 742 | } | |
| 743 | ||
| 744 | public void add(AsciiDocModel.Block block) { | |
| 745 | blocks.add(block); | |
| 746 |
1
1. add : Replaced integer addition with subtraction → SURVIVED |
size += block.size(); |
| 747 | } | |
| 748 | ||
| 749 | public List<AsciiDocModel.Block> all() { | |
| 750 |
1
1. all : replaced return value with Collections.emptyList for pro/verron/officestamper/asciidoc/DocxToAsciiDoc$BlockRecorder::all → KILLED |
return blocks; |
| 751 | } | |
| 752 | } | |
| 753 | ||
| 754 | } | |
Mutations | ||
| 73 |
1.1 |
|
| 74 |
1.1 |
|
| 75 |
1.1 |
|
| 76 |
1.1 |
|
| 79 |
1.1 |
|
| 89 |
1.1 |
|
| 90 |
1.1 |
|
| 91 |
1.1 |
|
| 92 |
1.1 |
|
| 95 |
1.1 |
|
| 99 |
1.1 |
|
| 104 |
1.1 |
|
| 106 |
1.1 |
|
| 123 |
1.1 2.2 |
|
| 124 |
1.1 |
|
| 125 |
1.1 |
|
| 131 |
1.1 |
|
| 135 |
1.1 2.2 |
|
| 139 |
1.1 |
|
| 140 |
1.1 |
|
| 141 |
1.1 |
|
| 142 |
1.1 |
|
| 147 |
1.1 2.2 |
|
| 151 |
1.1 2.2 |
|
| 155 |
1.1 2.2 |
|
| 165 |
1.1 |
|
| 166 |
1.1 |
|
| 177 |
1.1 |
|
| 178 |
1.1 |
|
| 187 |
1.1 |
|
| 191 |
1.1 |
|
| 200 |
1.1 |
|
| 206 |
1.1 |
|
| 207 |
1.1 |
|
| 211 |
1.1 |
|
| 219 |
1.1 |
|
| 223 |
1.1 |
|
| 224 |
1.1 |
|
| 225 |
1.1 2.2 |
|
| 226 |
1.1 2.2 |
|
| 229 |
1.1 |
|
| 230 |
1.1 |
|
| 232 |
1.1 |
|
| 239 |
1.1 |
|
| 251 |
1.1 |
|
| 258 |
1.1 |
|
| 259 |
1.1 |
|
| 267 |
1.1 |
|
| 270 |
1.1 |
|
| 274 |
1.1 |
|
| 275 |
1.1 |
|
| 279 |
1.1 2.2 |
|
| 284 |
1.1 |
|
| 288 |
1.1 |
|
| 292 |
1.1 |
|
| 295 |
1.1 |
|
| 296 |
1.1 |
|
| 298 |
1.1 |
|
| 299 |
1.1 |
|
| 301 |
1.1 |
|
| 302 |
1.1 |
|
| 304 |
1.1 |
|
| 305 |
1.1 |
|
| 307 |
1.1 |
|
| 308 |
1.1 |
|
| 310 |
1.1 |
|
| 319 |
1.1 |
|
| 320 |
1.1 |
|
| 327 |
1.1 2.2 |
|
| 332 |
1.1 |
|
| 333 |
1.1 |
|
| 334 |
1.1 |
|
| 338 |
1.1 2.2 |
|
| 340 |
1.1 2.2 |
|
| 342 |
1.1 |
|
| 343 |
1.1 |
|
| 359 |
1.1 |
|
| 360 |
1.1 |
|
| 362 |
1.1 |
|
| 364 |
1.1 |
|
| 369 |
1.1 |
|
| 370 |
1.1 |
|
| 371 |
1.1 |
|
| 373 |
1.1 |
|
| 374 |
1.1 |
|
| 375 |
1.1 |
|
| 376 |
1.1 |
|
| 377 |
1.1 |
|
| 378 |
1.1 |
|
| 379 |
1.1 |
|
| 380 |
1.1 |
|
| 381 |
1.1 |
|
| 383 |
1.1 |
|
| 384 |
1.1 |
|
| 385 |
1.1 |
|
| 386 |
1.1 |
|
| 387 |
1.1 |
|
| 388 |
1.1 2.2 |
|
| 393 |
1.1 |
|
| 395 |
1.1 |
|
| 396 |
1.1 |
|
| 397 |
1.1 |
|
| 400 |
1.1 |
|
| 402 |
1.1 2.2 |
|
| 403 |
1.1 |
|
| 404 |
1.1 2.2 |
|
| 405 |
1.1 |
|
| 406 |
1.1 2.2 |
|
| 407 |
1.1 |
|
| 408 |
1.1 2.2 |
|
| 409 |
1.1 |
|
| 410 |
1.1 2.2 |
|
| 411 |
1.1 |
|
| 412 |
1.1 2.2 |
|
| 413 |
1.1 |
|
| 414 |
1.1 2.2 |
|
| 415 |
1.1 |
|
| 418 |
1.1 |
|
| 420 |
1.1 2.2 |
|
| 421 |
1.1 |
|
| 422 |
1.1 2.2 |
|
| 423 |
1.1 |
|
| 424 |
1.1 |
|
| 425 |
1.1 2.2 |
|
| 426 |
1.1 |
|
| 429 |
1.1 |
|
| 430 |
1.1 |
|
| 431 |
1.1 |
|
| 433 |
1.1 2.2 |
|
| 434 |
1.1 |
|
| 435 |
1.1 2.2 |
|
| 436 |
1.1 |
|
| 437 |
1.1 |
|
| 441 |
1.1 |
|
| 442 |
1.1 |
|
| 443 |
1.1 |
|
| 446 |
1.1 |
|
| 448 |
1.1 |
|
| 450 |
1.1 |
|
| 451 |
1.1 2.2 |
|
| 455 |
1.1 |
|
| 461 |
1.1 |
|
| 462 |
1.1 |
|
| 467 |
1.1 |
|
| 469 |
1.1 2.2 |
|
| 470 |
1.1 |
|
| 473 |
1.1 |
|
| 474 |
1.1 |
|
| 476 |
1.1 |
|
| 477 |
1.1 2.2 |
|
| 487 |
1.1 |
|
| 491 |
1.1 |
|
| 496 |
1.1 |
|
| 497 |
1.1 |
|
| 499 |
1.1 |
|
| 505 |
1.1 |
|
| 506 |
1.1 |
|
| 514 |
1.1 |
|
| 519 |
1.1 |
|
| 526 |
1.1 |
|
| 537 |
1.1 |
|
| 538 |
1.1 |
|
| 539 |
1.1 2.2 |
|
| 544 |
1.1 |
|
| 547 |
1.1 |
|
| 550 |
1.1 |
|
| 553 |
1.1 |
|
| 560 |
1.1 |
|
| 564 |
1.1 |
|
| 571 |
1.1 2.2 |
|
| 581 |
1.1 2.2 |
|
| 590 |
1.1 |
|
| 591 |
1.1 |
|
| 598 |
1.1 2.2 |
|
| 609 |
1.1 2.2 |
|
| 645 |
1.1 |
|
| 662 |
1.1 |
|
| 669 |
1.1 |
|
| 679 |
1.1 |
|
| 697 |
1.1 |
|
| 702 |
1.1 |
|
| 705 |
1.1 2.2 |
|
| 718 |
1.1 |
|
| 741 |
1.1 |
|
| 746 |
1.1 |
|
| 750 |
1.1 |