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