Skip to content

Commit

Permalink
Only set text of paragraphs with placeholders
Browse files Browse the repository at this point in the history
To avoid overwriting runs which contain metainformation
(e.g. page number in footer), text replacement is only done for
paragraphs which contain placeholders.
  • Loading branch information
AntonOellerer committed Jun 6, 2024
1 parent f651da0 commit ec1b351
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 10 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ plugins {
}

group 'com.docutools'
version = '2.0.2'
version = '2.0.3'

java {
toolchain {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.List;
import java.util.Locale;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.util.LocaleUtil;
Expand Down Expand Up @@ -81,12 +82,10 @@ private void transform(XWPFTable table) {
private void transform(XWPFParagraph paragraph) {
Locale locale = WordUtilities.detectMostCommonLocale(paragraph)
.orElse(LocaleUtil.getUserLocale());
WordUtilities.replaceText(
paragraph,
TAG_PATTERN
.matcher(WordUtilities.toString(paragraph))
.replaceAll(matchResult -> fillPlaceholder(matchResult, locale))
);
Matcher matcher = TAG_PATTERN.matcher(WordUtilities.toString(paragraph));
if (matcher.find()) {
WordUtilities.replaceText(paragraph, matcher.replaceAll(matchResult -> fillPlaceholder(matchResult, locale)));
}
logger.debug("Transformed paragraph {}", paragraph);
}

Expand Down Expand Up @@ -131,8 +130,8 @@ private boolean isLoopStart(IBodyElement element, List<IBodyElement> remaining)
.map(placeholderData -> {
var endLoopMarkers = ParsingUtils.getMatchingLoopEnds(placeholderName);
return remaining.stream()
.filter(bodyElement -> bodyElement instanceof XWPFParagraph)
.map(bodyElement -> (XWPFParagraph)bodyElement)
.filter(XWPFParagraph.class::isInstance)
.map(XWPFParagraph.class::cast)
.map(XWPFParagraph::getText)
.anyMatch(text -> endLoopMarkers.contains(text.strip()));
}).orElse(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.docutools.jocument.impl.word;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
Expand All @@ -17,14 +18,18 @@
import com.docutools.jocument.impl.ReflectionResolver;
import com.docutools.jocument.sample.model.SampleModelData;
import com.docutools.jocument.sample.placeholders.QuotePlaceholder;
import com.docutools.jocument.sample.placeholders.TextPlaceholder;
import com.docutools.poipath.xwpf.XWPFDocumentWrapper;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import org.apache.poi.xwpf.usermodel.BodyElementType;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.xmlbeans.XmlAnySimpleType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
Expand Down Expand Up @@ -386,7 +391,7 @@ void shouldProcessDocumentWithTOC() throws IOException, InterruptedException {
assertThat(document.completed(), is(true));
xwpfDocument = TestUtils.getXWPFDocumentFromDocument(document);
var documentWrapper = new XWPFDocumentWrapper(xwpfDocument);
assertThat(documentWrapper.bodyElement(0).asParagraph().runs(), hasSize(1));
assertThat(documentWrapper.bodyElement(2).bodyElement().getElementType(), equalTo(BodyElementType.CONTENTCONTROL));
}

@Test
Expand Down Expand Up @@ -528,4 +533,33 @@ void pictureInHeader() throws InterruptedException, IOException {
xwpfDocument = TestUtils.getXWPFDocumentFromDocument(document);
assertThat(xwpfDocument.getHeaderArray(0).getAllPictures(), hasSize(1));
}

@Test
void keepsPageNumbering() throws InterruptedException, IOException {
// Arrange
Template template = Template.fromClassPath("/templates/word/PageNumberTemplate.docx")
.orElseThrow();
CustomPlaceholderRegistry customPlaceholderRegistry = new CustomPlaceholderRegistryImpl();
customPlaceholderRegistry.addHandler("text", TextPlaceholder.class);
PlaceholderResolver resolver = new ReflectionResolver(SampleModelData.PICARD, customPlaceholderRegistry);

// Act
Document document = template.startGeneration(resolver);
document.blockUntilCompletion(60000L); // 1 minute

// Assert
assertThat(document.completed(), is(true));
xwpfDocument = TestUtils.getXWPFDocumentFromDocument(document);
var instructions = xwpfDocument.getFooterArray(1)
.getListParagraph()
.stream()
.flatMap(xwpfParagraph -> xwpfParagraph.getRuns().stream())
.map(XWPFRun::getCTR)
.flatMap(ctr -> ctr.getInstrTextList().stream())
.map(XmlAnySimpleType::getStringValue)
.map(String::strip)
.toList();
assertThat(instructions, contains("PAGE", "NUMPAGES"));

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.docutools.jocument.sample.placeholders;

import com.docutools.jocument.GenerationOptions;
import com.docutools.jocument.impl.word.CustomWordPlaceholderData;
import com.docutools.jocument.impl.word.WordUtilities;
import java.util.Locale;
import org.apache.poi.xwpf.usermodel.IBody;
import org.apache.poi.xwpf.usermodel.IBodyElement;

public class TextPlaceholder extends CustomWordPlaceholderData {
@Override
protected void transform(IBodyElement placeholder, IBody part, Locale locale, GenerationOptions options) {
var paragraph = part.insertNewParagraph(WordUtilities.openCursor(placeholder).orElseThrow());
paragraph.createRun().setText("Live your life not celebrating victories, but overcoming defeats.".repeat(500));
WordUtilities.removeIfExists(placeholder);
}
}
Binary file not shown.

0 comments on commit ec1b351

Please sign in to comment.