Added optional "from" and "to" parameters [docgen.insertFile ...].
diff --git a/freemarker-docgen-core/pom.xml b/freemarker-docgen-core/pom.xml
index 6e43a71..84bd7e7 100644
--- a/freemarker-docgen-core/pom.xml
+++ b/freemarker-docgen-core/pom.xml
@@ -107,6 +107,11 @@
<artifactId>commons-io</artifactId>
<version>2.7</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-text</artifactId>
+ <version>1.9</version>
+ </dependency>
</dependencies>
<build>
diff --git a/freemarker-docgen-core/src/main/java/org/freemarker/docgen/core/PrintTextWithDocgenSubstitutionsDirective.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/core/PrintTextWithDocgenSubstitutionsDirective.java
index b7327e9..369d2f3 100644
--- a/freemarker-docgen-core/src/main/java/org/freemarker/docgen/core/PrintTextWithDocgenSubstitutionsDirective.java
+++ b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/core/PrintTextWithDocgenSubstitutionsDirective.java
@@ -29,11 +29,18 @@
import java.nio.charset.UnsupportedCharsetException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
+import org.apache.commons.text.StringEscapeUtils;
import freemarker.core.Environment;
import freemarker.core.HTMLOutputFormat;
@@ -139,12 +146,24 @@
skipWS();
String pathArg = fetchRequiredString();
String charsetArg = null;
- if (skipWS()) {
+ String fromArg = null;
+ String toArg = null;
+ Set<String> paramNamesSeen = new HashSet<>();
+ while (skipWS()) {
String paramName = fetchOptionalVariableName();
skipRequiredToken("=");
- String paramValue = fetchRequiredString();
+ String paramValue = StringEscapeUtils.unescapeXml(fetchRequiredString());
+ if (!paramNamesSeen.add(paramName)) {
+ throw new TemplateException(
+ "Duplicate " + StringUtil.jQuote(INSERT_FILE)
+ + " parameter " + StringUtil.jQuote(paramName) + ".", env);
+ }
if (paramName.equals("charset")) {
charsetArg = paramValue;
+ } else if (paramName.equals("from")) {
+ fromArg = paramValue;
+ } else if (paramName.equals("to")) {
+ toArg = paramValue;
} else {
throw new TemplateException(
"Unsupported " + StringUtil.jQuote(INSERT_FILE)
@@ -154,7 +173,7 @@
skipRequiredToken(DOCGEN_TAG_END);
lastUnprintedIdx = cursor;
- insertFile(pathArg, charsetArg);
+ insertFile(pathArg, charsetArg, fromArg, toArg);
} else {
throw new TemplateException(
"Unsupported docgen subvariable " + StringUtil.jQuote(subvarName) + ".", env);
@@ -216,7 +235,8 @@
}
}
- private void insertFile(String pathArg, String charsetArg) throws TemplateException, IOException {
+ private void insertFile(String pathArg, String charsetArg, String fromArg, String toArg)
+ throws TemplateException, IOException {
int slashIndex = pathArg.indexOf("/");
String symbolicNameStep = slashIndex != -1 ? pathArg.substring(0, slashIndex) : pathArg;
if (!symbolicNameStep.startsWith("@") || symbolicNameStep.length() < 2) {
@@ -261,6 +281,67 @@
if (fileExt != null && fileExt.toLowerCase().startsWith("ftl")) {
fileContent = removeFTLCopyrightComment(fileContent);
}
+
+ if (fromArg != null) {
+ boolean optional;
+ String fromArgCleaned;
+ if (fromArg.startsWith("?")) {
+ optional = true;
+ fromArgCleaned = fromArg.substring(1);
+ } else {
+ optional = false;
+ fromArgCleaned = fromArg;
+ }
+ Pattern from;
+ try {
+ from = Pattern.compile(fromArgCleaned);
+ } catch (PatternSyntaxException e) {
+ throw newErrorInDocgenTag("Invalid regular expression: " + fromArgCleaned);
+ }
+ Matcher matcher = from.matcher(fileContent);
+ if (matcher.find()) {
+ String remaining = fileContent.substring(matcher.start());
+ fileContent = "[\u2026]"
+ + (remaining.startsWith("\n") || remaining.startsWith("\r") ? "" : "\n")
+ + remaining;
+ } else {
+ if (!optional) {
+ throw newErrorInDocgenTag(
+ "Regular expression has no match in the file content: " + fromArg);
+ }
+ }
+ }
+
+ if (toArg != null) {
+ boolean optional;
+ String toArgCleaned;
+ if (toArg.startsWith("?")) {
+ optional = true;
+ toArgCleaned = toArg.substring(1);
+ } else {
+ optional = false;
+ toArgCleaned = toArg;
+ }
+ Pattern from;
+ try {
+ from = Pattern.compile(toArgCleaned);
+ } catch (PatternSyntaxException e) {
+ throw newErrorInDocgenTag("Invalid regular expression: " + toArgCleaned);
+ }
+ Matcher matcher = from.matcher(fileContent);
+ if (matcher.find()) {
+ String remaining = fileContent.substring(0, matcher.start());
+ fileContent = remaining
+ + (remaining.endsWith("\n") || remaining.endsWith("\r") ? "" : "\n")
+ + "[\u2026]";
+ } else {
+ if (!optional) {
+ throw newErrorInDocgenTag(
+ "Regular expression has no match in the file content: " + fromArg);
+ }
+ }
+ }
+
HTMLOutputFormat.INSTANCE.output(fileContent, out);
}
}