From 2026116ddb3486f9998d126174d0aa4941c84bf0 Mon Sep 17 00:00:00 2001 From: Ondrej Zizka Date: Tue, 24 Jul 2018 13:25:56 +0200 Subject: [PATCH 1/2] Improve hasHeader(): only scan first N lines, skip #... lines, skip blank lines, test against a regex; do not require status and type if defaults are set. --- .../java/org/jbake/parser/MarkupEngine.java | 72 ++++++++++++++++--- 1 file changed, 61 insertions(+), 11 deletions(-) diff --git a/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java b/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java index b0a4017df..c49f7774b 100644 --- a/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java +++ b/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java @@ -1,15 +1,5 @@ package org.jbake.parser; -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.io.IOUtils; -import org.jbake.app.Crawler; -import org.jbake.app.configuration.DefaultJBakeConfiguration; -import org.jbake.app.configuration.JBakeConfiguration; -import org.json.simple.JSONValue; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -17,9 +7,20 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; +import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.jbake.app.Crawler; +import org.jbake.app.configuration.DefaultJBakeConfiguration; +import org.jbake.app.configuration.JBakeConfiguration; +import org.json.simple.JSONValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Base class for markup engine wrappers. A markup engine is responsible for rendering @@ -35,6 +36,9 @@ public abstract class MarkupEngine implements ParserEngine { private JBakeConfiguration configuration; + public static final int MAX_HEADER_LINES = 50; + + /** * Tests if this markup engine can process the document. * @@ -156,12 +160,58 @@ private void setModelDefaultsIfNotSetInHeader(ParserContext context) { } } + /** * Checks if the file has a meta-data header. * * @param contents Contents of file * @return true if header exists, false if not */ + private boolean hasHeader2(Configuration config, List contents) { + boolean headerSeparatorFound = false; + boolean statusFound = false; + boolean typeFound = false; + + List headerLines = new ArrayList<>(); + + + //for (String line : contents) { + for (int i = 0; i < contents.size() && i < MAX_HEADER_LINES; i++) { + String line = contents.get(i); + if (StringUtils.isBlank(line)) + continue; + + if (line.startsWith("#")) + continue; + + if (line.equals(configuration.getHeaderSeparator())) { + headerSeparatorFound = true; + break; + } + + if (!line.matches("^\\p{Graph}+\\p{Blank}*(=|:)\\p{Blank}*\\p{Graph}*")) + continue; + + headerLines.add(line); + + typeFound |= line.startsWith("type="); + statusFound |= line.startsWith("status="); + } + + if (headerSeparatorFound) { + for (String headerLine : headerLines) { + if (!headerLine.contains("=")) { + LOGGER.warn("Document has invalid header line (without '='):\n{}", headerLines); + return false; + } + } + } + + return (statusFound || null != configuration.getDefaultStatus()) + && (typeFound || null != configuration.getDefaultType()); + } + + private boolean hasHeader(List contents) { boolean headerValid = true; boolean statusFound = false; @@ -332,4 +382,4 @@ private void processDefaultBody(ParserContext context) { } context.setBody(body.toString()); } -} \ No newline at end of file +} From 462023f2b1cd49ea8a57e92b918bc1d2b32aa3b2 Mon Sep 17 00:00:00 2001 From: Ondrej Zizka Date: Wed, 1 Aug 2018 04:52:19 +0200 Subject: [PATCH 2/2] Only scan a limited number of lines for a headers block separator. --- .../DefaultJBakeConfiguration.java | 20 +++++++++++++------ .../app/configuration/JBakeConfiguration.java | 6 ++++++ .../app/configuration/JBakeProperty.java | 1 + .../java/org/jbake/parser/MarkupEngine.java | 6 ++---- .../src/main/resources/default.properties | 4 +++- 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/DefaultJBakeConfiguration.java b/jbake-core/src/main/java/org/jbake/app/configuration/DefaultJBakeConfiguration.java index 7a772acb8..8ee6816be 100644 --- a/jbake-core/src/main/java/org/jbake/app/configuration/DefaultJBakeConfiguration.java +++ b/jbake-core/src/main/java/org/jbake/app/configuration/DefaultJBakeConfiguration.java @@ -1,11 +1,5 @@ package org.jbake.app.configuration; -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.io.File; import java.util.ArrayList; import java.util.Arrays; @@ -13,6 +7,11 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The default implementation of a {@link JBakeConfiguration} @@ -32,6 +31,9 @@ public class DefaultJBakeConfiguration implements JBakeConfiguration { private Logger logger = LoggerFactory.getLogger(DefaultJBakeConfiguration.class); private CompositeConfiguration compositeConfiguration; + public static final int MAX_HEADER_LINES_DEFAULT = 50; + + /** * Some deprecated implementations just need access to the configuration without access to the source folder * @@ -468,6 +470,12 @@ public String getVersion() { return getAsString(JBakeProperty.VERSION); } + @Override + public int getMaxHeaderLinesScan() + { + return getAsInt(JBakeProperty.MAX_HEADER_LINES_SCAN, MAX_HEADER_LINES_DEFAULT); + } + public void setDestinationFolderName(String folderName) { setProperty(JBakeProperty.DESTINATION_FOLDER, folderName); setupDefaultDestination(); diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfiguration.java b/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfiguration.java index 5e5435382..ca845a9ec 100644 --- a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfiguration.java +++ b/jbake-core/src/main/java/org/jbake/app/configuration/JBakeConfiguration.java @@ -299,6 +299,12 @@ public interface JBakeConfiguration { */ String getVersion(); + /** + * @return Maximum lines to scan when looking for a JBake in-file header. + */ + int getMaxHeaderLinesScan(); + + /** * Set a property value for the given key * diff --git a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeProperty.java b/jbake-core/src/main/java/org/jbake/app/configuration/JBakeProperty.java index 375d8f903..8992edfd0 100644 --- a/jbake-core/src/main/java/org/jbake/app/configuration/JBakeProperty.java +++ b/jbake-core/src/main/java/org/jbake/app/configuration/JBakeProperty.java @@ -46,6 +46,7 @@ public class JBakeProperty { public static final String IMG_PATH_UPDATE = "img.path.update"; public static final String IMG_PATH_PREPEND_HOST = "img.path.prepend.host"; public static final String VERSION = "version"; + public static final String MAX_HEADER_LINES_SCAN = "header.maxLines"; private JBakeProperty() {} diff --git a/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java b/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java index c49f7774b..7a493b009 100644 --- a/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java +++ b/jbake-core/src/main/java/org/jbake/parser/MarkupEngine.java @@ -36,9 +36,6 @@ public abstract class MarkupEngine implements ParserEngine { private JBakeConfiguration configuration; - public static final int MAX_HEADER_LINES = 50; - - /** * Tests if this markup engine can process the document. * @@ -174,9 +171,10 @@ private boolean hasHeader2(Configuration config, List contents) { List headerLines = new ArrayList<>(); + int scanMaxLines = configuration.getMaxHeaderLinesScan(); //for (String line : contents) { - for (int i = 0; i < contents.size() && i < MAX_HEADER_LINES; i++) { + for (int i = 0; i < contents.size() && i < scanMaxLines; i++) { String line = contents.get(i); if (StringUtils.isBlank(line)) continue; diff --git a/jbake-core/src/main/resources/default.properties b/jbake-core/src/main/resources/default.properties index a6a66fa28..664268f56 100644 --- a/jbake-core/src/main/resources/default.properties +++ b/jbake-core/src/main/resources/default.properties @@ -116,4 +116,6 @@ header.separator=~~~~~~ # update image path img.path.update=false # Prepend site.host to image paths -img.path.prepend.host=true \ No newline at end of file +img.path.prepend.host=true +# JBake will only scan this number of lines for a headers block separator. +header.maxLines=50