You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by sg...@apache.org on 2020/06/25 14:33:21 UTC

[freemarker-generator] branch FREEMARKER-147 updated: FREEMARKER-147 Complete Maven site documenation

This is an automated email from the ASF dual-hosted git repository.

sgoeschl pushed a commit to branch FREEMARKER-147
in repository https://gitbox.apache.org/repos/asf/freemarker-generator.git


The following commit(s) were added to refs/heads/FREEMARKER-147 by this push:
     new 05abdc4  FREEMARKER-147 Complete Maven site documenation
05abdc4 is described below

commit 05abdc4427e720634cf461ebf1cc588c669ab58b
Author: Siegfried Goeschl <si...@gmail.com>
AuthorDate: Thu Jun 25 16:32:59 2020 +0200

    FREEMARKER-147 Complete Maven site documenation
---
 .travis.yml                                        |  2 +-
 README.md                                          | 14 ++++-
 .../generator/base/datasource/DataSources.java     | 17 +++---
 .../generator/base/template/TemplateSource.java    | 21 ++++++++
 .../generator/datasource/DataSourcesTest.java      |  1 -
 .../template/TemplateSourceFactoryTest.java        | 11 ++--
 freemarker-generator-cli/README.md                 |  2 +-
 .../examples/templates/info.ftl                    |  2 +-
 freemarker-generator-cli/pom.xml                   |  1 +
 .../cli/{usage => advanced}/cli-configuration.md   |  2 +-
 .../src/site/markdown/cli/concepts/data-models.md  | 35 ++++++++++---
 .../src/site/markdown/cli/concepts/data-sources.md | 25 +++++++++
 .../{user-parameters.md => passing-data.md}        | 17 +++++-
 .../markdown/cli/concepts/template-includes.md     | 17 ------
 .../site/markdown/cli/concepts/template-loading.md | 53 +++++++++++--------
 .../cli/{tools/overview.md => concepts/tools.md}   |  6 ++-
 .../site/markdown/cli/concepts/transformation.md   |  2 +-
 .../site/markdown/cli/usage/transforming-csv.md    | 60 ++++++++++++++++++++++
 .../markdown/cli/usage/transforming-directories.md |  4 +-
 .../dataframe.md => usage/using-dataframes.md}     |  6 +--
 .../src/site/markdown/index.md                     | 26 +++++++---
 .../freemarker/generator/cli/ManualTest.java       |  4 +-
 .../templates/csv/csv/transform.ftl                |  7 ++-
 freemarker-generator-cli/templates/info.ftl        |  2 +-
 .../templates/lib/commons-csv.ftl                  |  8 +--
 .../generator/tools/commonscsv/CommonsCSVTool.java |  3 +-
 .../{ => impl}/CommonsCSVPrinterFacade.java        |  2 +-
 .../generator/tools/dataframe/DataFrameTool.java   |  6 +--
 .../{converter => impl}/CSVConverter.java          |  2 +-
 .../{converter => impl}/ConverterUtils.java        |  2 +-
 .../{converter => impl}/ListConverter.java         |  2 +-
 .../{converter => impl}/MapConverter.java          |  4 +-
 .../generator/tools/freemarker/FreeMarkerTool.java | 19 +++++--
 .../freemarker/generator/tools/grok/GrokTool.java  |  1 +
 .../tools/grok/{ => impl}/GrokWrapper.java         |  2 +-
 .../tools/commonscsv/CommonsCSVToolTest.java       |  1 +
 .../generator/tools/grok/GrokToolTest.java         |  1 +
 src/site/markdown/index.md                         |  2 -
 travis.sh                                          | 22 +++++++-
 39 files changed, 305 insertions(+), 109 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index b3680d5..5e13867 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,7 +7,7 @@ jdk:
   - openjdk12
   - openjdk13
 script:
-  - mvn clean install
+  - mvn clean install site site:stage
   - cd ./freemarker-generator-cli
   - sh ./run-examples.sh
   - cd ../freemarker-generator-maven-plugin-sample
diff --git a/README.md b/README.md
index efc2fc2..c350765 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,6 @@ Apache FreeMarker Generator
 
 For documentation or to report bugs visit: [https://freemarker.apache.org](https://freemarker.apache.org)
 
-
 Regarding pull requests on Github
 -----------------------------------------------------------------------------
 
@@ -15,7 +14,6 @@ a [Contributor License Agreement](https://www.apache.org/dev/new-committers-guid
 For contributions that are judged to be non-trivial, you will be asked
 to actually signing a Contributor License Agreement.
 
-
 What is Apache FreeMarker Generator?
 -----------------------------------------------------------------------------
 
@@ -28,6 +26,18 @@ Currently it can be invoked as a
 * Command-line interface `freemarker-generator-cli`
 * Maven plug-in `freemarker-generator-maven-plugin`
 
+Building Apache FreeMarker Generator
+-----------------------------------------------------------------------------
+
+To create the artefacts locally run
+
+> mvn clean install
+
+To build the documentation site run
+
+> mvn clean site site:stage
+
+To 
 
 Licensing
 -----------------------------------------------------------------------------
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSources.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSources.java
index 4c6e156..9db5552 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSources.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSources.java
@@ -16,8 +16,10 @@
  */
 package org.apache.freemarker.generator.base.datasource;
 
+import org.apache.commons.io.FilenameUtils;
 import org.apache.freemarker.generator.base.util.ClosableUtils;
 import org.apache.freemarker.generator.base.util.StringUtils;
+import org.apache.freemarker.generator.base.util.Validate;
 
 import java.io.Closeable;
 import java.util.ArrayList;
@@ -25,7 +27,6 @@ import java.util.Collection;
 import java.util.List;
 
 import static java.util.stream.Collectors.toList;
-import static org.apache.commons.io.FilenameUtils.wildcardMatch;
 
 /**
  * Container for data sources with a couple of convenience functions to select
@@ -36,13 +37,14 @@ public class DataSources implements Closeable {
     private final List<DataSource> dataSources;
 
     public DataSources(Collection<DataSource> dataSources) {
+        Validate.notNull(dataSources, "No data sources provided");
         this.dataSources = new ArrayList<>(dataSources);
     }
 
     /**
      * Get the names of all data sources.
      *
-     * @return datas ource names
+     * @return data source names
      */
     public List<String> getNames() {
         return dataSources.stream()
@@ -109,24 +111,24 @@ public class DataSources implements Closeable {
     /**
      * Find data sources based on their name and globbing pattern.
      *
-     * @param wildcard globbing pattern
+     * @param wildcard the wildcard string to match against
      * @return list of matching data sources
      */
     public List<DataSource> find(String wildcard) {
         return dataSources.stream()
-                .filter(d -> wildcardMatch(d.getName(), wildcard))
+                .filter(d -> FilenameUtils.wildcardMatch(d.getName(), wildcard))
                 .collect(toList());
     }
 
     /**
      * Find data sources based on their group and and globbing pattern.
      *
-     * @param wildcard globbing pattern
+     * @param wildcard the wildcard string to match against
      * @return list of mathching data sources
      */
     public List<DataSource> findByGroup(String wildcard) {
         return dataSources.stream()
-                .filter(d -> wildcardMatch(d.getGroup(), wildcard))
+                .filter(d -> FilenameUtils.wildcardMatch(d.getGroup(), wildcard))
                 .collect(toList());
     }
 
@@ -139,9 +141,6 @@ public class DataSources implements Closeable {
     public String toString() {
         return "DataSource{" +
                 "dataSources=" + dataSources +
-                ", names=" + getNames() +
-                ", groups=" + getGroups() +
-                ", size=" + size() +
                 '}';
     }
 }
diff --git a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/template/TemplateSource.java b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/template/TemplateSource.java
index 4bc86bf..c12d35a 100644
--- a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/template/TemplateSource.java
+++ b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/template/TemplateSource.java
@@ -64,17 +64,38 @@ public class TemplateSource {
         this.encoding = encoding;
     }
 
+    /**
+     * Template will be loaded from path using a file-base template loader.
+     *
+     * @param path template path
+     * @return file-based template source
+     */
     public static TemplateSource fromPath(String path) {
         Validate.notEmpty(path, "Template path is empty");
         return new TemplateSource(path, path, StandardCharsets.UTF_8);
     }
 
+    /**
+     * Template will be loaded from path using a file-base template loader.
+     *
+     * @param path template path
+     * @param encoding character encoding og template
+     * @return file-based template source
+     */
+
     public static TemplateSource fromPath(String path, Charset encoding) {
         Validate.notEmpty(path, "Template path is empty");
         Validate.notNull(encoding, "Template encoding is null");
         return new TemplateSource(path, path, encoding);
     }
 
+    /**
+     * Template will be loaded from a literal content.
+     *
+     * @param name name of the template
+     * @param code template code
+     * @return template source
+     */
     public static TemplateSource fromCode(String name, String code) {
         Validate.notEmpty(name, "Template name is empty");
         Validate.notEmpty(code, "Template code is empty");
diff --git a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesTest.java b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesTest.java
index b4cf812..c97de8f 100644
--- a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesTest.java
+++ b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesTest.java
@@ -90,7 +90,6 @@ public class DataSourcesTest {
         assertEquals("unknown", dataSources().get(0).getName());
         assertEquals("pom.xml", dataSources().get(1).getName());
         assertEquals("server.invalid", dataSources().get(2).getName());
-        assertEquals("unknown", dataSources().getFirst().getName());
         assertEquals(3, dataSources.getList().size());
         assertEquals(3, dataSources.size());
         assertFalse(dataSources.isEmpty());
diff --git a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/template/TemplateSourceFactoryTest.java b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/template/TemplateSourceFactoryTest.java
index 1d84c90..7a40e52 100644
--- a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/template/TemplateSourceFactoryTest.java
+++ b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/template/TemplateSourceFactoryTest.java
@@ -31,9 +31,8 @@ public class TemplateSourceFactoryTest {
 
     private static final String ANY_TEMPLATE_PATH = "any/template/path.ftl";
     private static final String ANY_FILE_NAME = "pom.xml";
-    private static final String ANY_URL = "https://jsonplaceholder.typicode.com/posts/2";
+    private static final String ANY_URL = "https://raw.githubusercontent.com/apache/freemarker-generator/master/freemarker-generator-cli/templates/info.ftl";
     private static final String ANY_ENVIRONMENT_VARIABLE = "env:///PWD";
-    private static final String ANY_NAMED_URI = "content:www=https://www.google.com?foo=bar#contenttype=application/json";
 
     @Test
     public void shouldCreateFromTemplatePath() {
@@ -66,7 +65,7 @@ public class TemplateSourceFactoryTest {
     }
 
     @Test
-    @Ignore("Requires internet access")
+    // @Ignore("Requires internet access")
     public void shouldCreateFromUrl() {
         final TemplateSource templateSource = TemplateSourceFactory.create(ANY_URL);
 
@@ -77,11 +76,11 @@ public class TemplateSourceFactoryTest {
     }
 
     @Test
-    @Ignore("Requires internet access")
+    // @Ignore("Requires internet access")
     public void shouldCreateFromNamedUri() {
-        final TemplateSource templateSource = TemplateSourceFactory.create(ANY_NAMED_URI);
+        final TemplateSource templateSource = TemplateSourceFactory.create("info=" + ANY_URL);
 
-        assertNotNull(templateSource.getName());
+        assertEquals("info", templateSource.getName());
         assertEquals(Origin.CODE, templateSource.getOrigin());
         assertNull(templateSource.getPath());
         assertFalse(templateSource.getCode().isEmpty());
diff --git a/freemarker-generator-cli/README.md b/freemarker-generator-cli/README.md
index 9573c1a..ea8b379 100644
--- a/freemarker-generator-cli/README.md
+++ b/freemarker-generator-cli/README.md
@@ -86,7 +86,7 @@ Timestamp              : Jun 18, 2020 10:55:04 AM
 Output encoding        : UTF-8
 Output format          : plainText
 
-FreeMarker CLI Template Directories
+FreeMarker CLI Template Loader Directories
 ------------------------------------------------------------------------------
 [#1] /Users/sgoeschl/work/github/apache/freemarker-generator/freemarker-generator-cli/target/appassembler
 [#2] /Users/sgoeschl/.freemarker-cli
diff --git a/freemarker-generator-cli/examples/templates/info.ftl b/freemarker-generator-cli/examples/templates/info.ftl
index 565e2ec..9de3a13 100644
--- a/freemarker-generator-cli/examples/templates/info.ftl
+++ b/freemarker-generator-cli/examples/templates/info.ftl
@@ -25,7 +25,7 @@ Timestamp              : ${.now}
 Output encoding        : ${.output_encoding}
 Output format          : ${.output_format}
 
-FreeMarker CLI Template Directories
+FreeMarker CLI Template Loader Directories
 ------------------------------------------------------------------------------
 <#list SystemTool.getTemplateDirectories() as directory>
 [#${directory?counter}] ${directory}
diff --git a/freemarker-generator-cli/pom.xml b/freemarker-generator-cli/pom.xml
index 55482df..443b739 100644
--- a/freemarker-generator-cli/pom.xml
+++ b/freemarker-generator-cli/pom.xml
@@ -67,6 +67,7 @@
                 <artifactId>maven-antrun-plugin</artifactId>
                 <executions>
                     <execution>
+                        <id>package</id>
                         <phase>package</phase>
                         <configuration>
                             <target>
diff --git a/freemarker-generator-cli/src/site/markdown/cli/usage/cli-configuration.md b/freemarker-generator-cli/src/site/markdown/cli/advanced/cli-configuration.md
similarity index 98%
rename from freemarker-generator-cli/src/site/markdown/cli/usage/cli-configuration.md
rename to freemarker-generator-cli/src/site/markdown/cli/advanced/cli-configuration.md
index 499f3c2..cde2cd1 100644
--- a/freemarker-generator-cli/src/site/markdown/cli/usage/cli-configuration.md
+++ b/freemarker-generator-cli/src/site/markdown/cli/advanced/cli-configuration.md
@@ -69,7 +69,7 @@ You can easily check this, e.g.
 ```
 > freemarker-cli -t templates/info.ftl
 
-FreeMarker CLI Template Directories
+FreeMarker CLI Template Loader Directories
 ------------------------------------------------------------------------------
 [#1] /Users/sgoeschl
 [#2] /Users/sgoeschl/.freemarker-cli
diff --git a/freemarker-generator-cli/src/site/markdown/cli/concepts/data-models.md b/freemarker-generator-cli/src/site/markdown/cli/concepts/data-models.md
index c8707c7..7c53574 100644
--- a/freemarker-generator-cli/src/site/markdown/cli/concepts/data-models.md
+++ b/freemarker-generator-cli/src/site/markdown/cli/concepts/data-models.md
@@ -9,21 +9,44 @@ A `DataModel` is an eagerly loaded `DataSource` available in Apache FreeMarker's
 Expose the fields of the JSON data source in FreeMarker's model 
 
 ```
-bin/freemarker-cli --data-model https://xkcd.com/info.0.json  -i '<a href="${img}">${title}</a>'; echo
-<a href="https://imgs.xkcd.com/comics/scenario_4.png">Scenario 4</a>
+> curl -s https://xkcd.com/info.0.json | python -m json.tool
+{
+    "alt": "The git vehicle fleet eventually pivoted to selling ice cream, but some holdovers remain. If you flag down an ice cream truck and hand the driver a floppy disk, a few hours later you'll get an invite to a git repo.",
+    "day": "24",
+    "img": "https://imgs.xkcd.com/comics/old_days_2.png",
+    "link": "",
+    "month": "6",
+    "news": "",
+    "num": 2324,
+    "safe_title": "Old Days 2",
+    "title": "Old Days 2",
+    "transcript": "",
+    "year": "2020"
+}
+
+> freemarker-cli --data-model https://xkcd.com/info.0.json  -i '<a href="${img}">${title}</a>'; echo
+<a href="https://imgs.xkcd.com/comics/old_days_2.png">Old Days 2</a>
 ```
 
 Exposed the JSON data source as variable `post` in FreeMarker's model 
 
 ```
-bin/freemarker-cli --data-model post=https://jsonplaceholder.typicode.com/posts/2 -i 'post title is: ${post.title}'; echo
+> curl -s https://jsonplaceholder.typicode.com/posts/2 | python -m json.tool
+{
+    "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla",
+    "id": 2,
+    "title": "qui est esse",
+    "userId": 1
+}
+
+> freemarker-cli --data-model post=https://jsonplaceholder.typicode.com/posts/2 -i 'post title is: ${post.title}'; echo
 post title is: qui est esse
 ```
 
 Expose all environment variables as `env` in theFreeMarker model
  
 ```
-bin/freemarker-cli --data-model env=env:/// -i '<#list env as name,value>${name}=${value}${"\n"}</#list>'
+> freemarker-cli --data-model env=env:/// -i '<#list env as name,value>${name}=${value}${"\n"}</#list>'
 HOME=/Users/sgoeschl
 USER=sgoeschl
 ```
@@ -31,14 +54,14 @@ USER=sgoeschl
 Expose a single envionment variable in theFreeMarker model
 
 ```
-bin/freemarker-cli --data-model NAME=env:///USER -i 'Hello ${NAME}'; echo
+> freemarker-cli --data-model NAME=env:///USER -i 'Hello ${NAME}'; echo
 Hello sgoeschl
 ```
 
 Alternatively use the short command line options, e.g.
 
 ```
-bin/freemarker-cli -m NAME=env:///USER -i 'Hello ${NAME}!'; echo
+> freemarker-cli -m NAME=env:///USER -i 'Hello ${NAME}!'; echo
 Hello sgoeschl!
 ```
 
diff --git a/freemarker-generator-cli/src/site/markdown/cli/concepts/data-sources.md b/freemarker-generator-cli/src/site/markdown/cli/concepts/data-sources.md
index 0eafef8..c97873c 100644
--- a/freemarker-generator-cli/src/site/markdown/cli/concepts/data-sources.md
+++ b/freemarker-generator-cli/src/site/markdown/cli/concepts/data-sources.md
@@ -82,5 +82,30 @@ FreeMarker CLI DataSources
     URI : file:/Users/sgoeschl/work/github/apache/freemarker-generator/freemarker-generator-cli/target/appassembler/examples/data/json/github-users.json
     [#2], name=swagger-spec.json, group=default, contentType=application/json, charset=UTF-8, length=24,948 Bytes
     URI : file:/Users/sgoeschl/work/github/apache/freemarker-generator/freemarker-generator-cli/target/appassembler/examples/data/json/swagger-spec.json
+```
+
+### Selecting A DataSource
+
+After loading one or more `DataSource` it needs to be selected for template processing - the `DataSources` instance 
+exposed in the data model provides
+
+* Selecting by index  
+* Selecting by name
+* Filter by the globbing pattern (see [Apache Commons IO](https://commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/filefilter/WildcardFileFilter.html))
+
+A few FTL examples
 
 ```
+<#assign dataSource = DataSources.get(0)>
+
+<#assign dataSource = DataSources.get("user.csv)>
+
+<#list DataSources.find("*.md") as dataSource>
+- ${dataSource.name}
+</#list>
+```
+
+
+
+ 
+
diff --git a/freemarker-generator-cli/src/site/markdown/cli/concepts/user-parameters.md b/freemarker-generator-cli/src/site/markdown/cli/concepts/passing-data.md
similarity index 73%
rename from freemarker-generator-cli/src/site/markdown/cli/concepts/user-parameters.md
rename to freemarker-generator-cli/src/site/markdown/cli/concepts/passing-data.md
index b4957f5..71f1b75 100644
--- a/freemarker-generator-cli/src/site/markdown/cli/concepts/user-parameters.md
+++ b/freemarker-generator-cli/src/site/markdown/cli/concepts/passing-data.md
@@ -1,4 +1,19 @@
-## User-Supplied Parameters
+## Passing Configuration Data
+
+`Apache FreeMarker CLI` provides multiple ways to pass configuration data used in in templates
+
+* System properties
+* Parameters 
+
+### User-Supplied System Poperties
+
+User-supplied system properties are added to the JVM's system properties
+
+```
+> freemarker-cli -Dfoo1=foo1 -D foo2=foo2 -t templates/info.ftl 
+```
+ 
+### User-Supplied Parameters
 
 User-supplied parameters allow to pass additional information to an Apache FreeMarker template 
 
diff --git a/freemarker-generator-cli/src/site/markdown/cli/concepts/template-includes.md b/freemarker-generator-cli/src/site/markdown/cli/concepts/template-includes.md
deleted file mode 100644
index 8aa0dc3..0000000
--- a/freemarker-generator-cli/src/site/markdown/cli/concepts/template-includes.md
+++ /dev/null
@@ -1,17 +0,0 @@
-### Template Includes
-
-When writing more and more templates you find reusable snippets which should not be copy/pasted but organized as [templates includes](https://freemarker.apache.org/docs/ref_directive_include.html).
-
-E.g. `Apache Commons CSV` FTL code is included as shown below
-
-```
-<#import "/templates/lib/commons-csv.ftl" as csv />
-<#assign dataSource = DataSources.get(0)>
-<#assign csvParser = CSVTool.parse(dataSource, csv.sourceFormat())>
-```
-
-What is happening here?
-
-* The template loader picks up `/templates/lib/commons-csv.ftl` from the `Apache FreeMarker CLI` installation directory and imports it as `csv`
-* The imported template exports two methods `csv.sourceFormat()` and `csv.targetFormat()` 
-* The exposed methods do the right thing based on the user-supplied parameters and can be re-used for all CSV related templates
diff --git a/freemarker-generator-cli/src/site/markdown/cli/concepts/template-loading.md b/freemarker-generator-cli/src/site/markdown/cli/concepts/template-loading.md
index 15ce5a3..f54228e 100644
--- a/freemarker-generator-cli/src/site/markdown/cli/concepts/template-loading.md
+++ b/freemarker-generator-cli/src/site/markdown/cli/concepts/template-loading.md
@@ -1,47 +1,60 @@
 ## Template Loading
 
-`Apache FreeMarker CLI` loads templates from multiple locations in the following order
+In order the render a template it needs to be loaded first - there are multiple ways of creating/loading a template
+
+* Using a [FreeMarker Template Loader](https://freemarker.apache.org/docs/pgui_config_templateloading.html) and abstract template paths 
+* Load a template without template loader (aka free-style template loading), e.g. absolute template file, a directory or an URL
+* Provide the template directly on the command-line (aka interactive template)
+
+### FreeMarker MultiTemplateLoader
+
+`Apache FreeMarker CLI` uses a `MultiTemplateLoader` searching for templates in the following directories
 
 * Current working directory
 * Optional `~/.freemarker-cli` directory
 * `Apache FreeMarker CLI` installation directory
 
-You can check the available template locations easily on the command line
+You can check the currently used template loader directories easily on the command line, e.g.
 
 ```
 freemarker-cli -t templates/info.ftl
 
-FreeMarker CLI Template Directories
+FreeMarker CLI Template Loader Directories
 ------------------------------------------------------------------------------
 [#1] /Users/sgoeschl/work/github/apache/freemarker-generator
 [#2] /Users/sgoeschl/.freemarker-cli
 [#3] /Applications/Java/freemarker-cli-2.0.0
 ```
 
-### Template Loaders In Action
-
-Let's assume you have `freemarker-cli` in your path and you execute
+The main benefit of `MultiTemplateLoader` is the use of abstract template paths finding a template in the template loader directories
 
 ```
-> cd /
-> which freemarker-cli
-/Applications/Java/freemarker-cli-2.0.0/bin/freemarker-cli
-> freemarker-cli -t templates/cat.ftl https://jsonplaceholder.typicode.com/posts/2
-{
-  "userId": 1,
-  "id": 2,
-  "title": "qui est esse",
-  "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
-}
+freemarker-cli -t templates/info.ftl
+``` 
+
+and [Template Includes](https://freemarker.apache.org/docs/ref_directive_include.html)
+
 ```
+<#import "/templates/lib/commons-csv.ftl" as csv />
+```  
+
+### Free-Style Template Loading
+
+The previosly described `Template Loaders` do not support absolute template files or arbitraRY URLS - this behaviour 
+stems from security aspects when running `Apache FreeMarker` on the server side. For a command-line tool this is mostly
+irrelevant therefore any template file outside of the template loader directories can be loaded 
 
-In your root directory there is no `templates/cat.ftl` but it is picked up from `/Applications/Java/freemarker-cli-2.0.0`
+This example loads the `info.ftl` directly from a GitHub URL
+
+```
+freemarker-cli -t https://raw.githubusercontent.com/apache/freemarker-generator/master/freemarker-generator-cli/templates/info.ftl
+```
 
-### Literal Templates
+### Interactive Template Loading
 
-You can also directly specify a template to be loaded without relying on template loaders
+The template can be defined directly on the command line in case of trivial transformations
 
 ```
-freemarker-cli -t some-directory/transform.ftl some-directory/contract.csv
+freemarker-cli -i '${GsonTool.toJson(yaml)}' -m yaml=examples/data/yaml/swagger-spec.yaml
 ```
 
diff --git a/freemarker-generator-cli/src/site/markdown/cli/tools/overview.md b/freemarker-generator-cli/src/site/markdown/cli/concepts/tools.md
similarity index 91%
rename from freemarker-generator-cli/src/site/markdown/cli/tools/overview.md
rename to freemarker-generator-cli/src/site/markdown/cli/concepts/tools.md
index e5a64c6..c07a01a 100644
--- a/freemarker-generator-cli/src/site/markdown/cli/tools/overview.md
+++ b/freemarker-generator-cli/src/site/markdown/cli/concepts/tools.md
@@ -1,6 +1,8 @@
-## Overview
+## Tools
 
-The following `tools` are currently implemented
+A `Apache FreeMarker CLI Tool` is just a POJO (plain old Java object) that is "useful" in a template and is not meant to be rendered in the output.
+
+The following tools are currently implemented
 
 | Tool                  | Description                                                                                               |
 |-----------------------|-----------------------------------------------------------------------------------------------------------|
diff --git a/freemarker-generator-cli/src/site/markdown/cli/concepts/transformation.md b/freemarker-generator-cli/src/site/markdown/cli/concepts/transformation.md
index be6da2f..388a681 100644
--- a/freemarker-generator-cli/src/site/markdown/cli/concepts/transformation.md
+++ b/freemarker-generator-cli/src/site/markdown/cli/concepts/transformation.md
@@ -11,4 +11,4 @@ The `freemarker-cli` generates text output based on FreeMarker templates and dat
     * an output directory
 * When the output is written to a directory
     * the structure of the input directory is preserved
-    * a `ftl file externsion is removed
+    * a `ftl` file externsion is removed
diff --git a/freemarker-generator-cli/src/site/markdown/cli/usage/transforming-csv.md b/freemarker-generator-cli/src/site/markdown/cli/usage/transforming-csv.md
new file mode 100644
index 0000000..14667b8
--- /dev/null
+++ b/freemarker-generator-cli/src/site/markdown/cli/usage/transforming-csv.md
@@ -0,0 +1,60 @@
+## Working With CSV
+
+A common task is changing the output format of a CSV file
+
+* Convert a CSV into a different format
+* Convert a CSV into Markdown or HTML
+
+### Convert CSV To A Different Output Format
+
+Let's assume that a CSV file in [DEFAULT format](https://commons.apache.org/proper/commons-csv/apidocs/org/apache/commons/csv/CSVFormat.html#DEFAULT) 
+should be converted into a [Microsoft Excel compatible format](https://commons.apache.org/proper/commons-csv/apidocs/org/apache/commons/csv/CSVFormat.html#EXCEL).
+This allows opening the CSV directly in Excel without going to the tedious CSV import form.
+
+The following command line prints the converted CSV to `stdout`
+
+```
+freemarker-cli \
+ -PCSV_SOURCE_FORMAT=DEFAULT \
+ -PCSV_TARGET_FORMAT=EXCEL \
+ -PCSV_TARGET_DELIMITER=SEMICOLON \
+ -t templates/csv/csv/transform.ftl \
+ https://raw.githubusercontent.com/apache/freemarker-generator/master/freemarker-generator-cli/examples/data/csv/contract.csv 
+```  
+
+The command line invocation seems a bit complex at first so let's look at it more closely
+
+* `CSV_SOURCE_FORMAT` defines the CSV source format for reading the CSV
+* `CSV_TARGET_FORMAT` defines the CSV tagrte format for writing the CSV
+* `CSV_TARGET_DELIMITER` explicitely sets the delimiter of the target CSV to a semicolon since this expected by Excel for my current locale
+
+### Convert CSV To Markdown
+
+When doing documentation it is sometimes helpful to convert a CSV into its Markdown representation (AsciiDoc 
+actually allows including CSV directly)
+
+The following command line prints the resulting MarkDown to `stdout`
+
+```
+freemarker-cli \
+ -PCSV_SOURCE_FORMAT=DEFAULT \
+ -t templates/csv/md/transform.ftl \
+ https://raw.githubusercontent.com/apache/freemarker-generator/master/freemarker-generator-cli/examples/data/csv/contract.csv 
+```  
+
+Please note that most MarkDown tools expect a header row (see [Create a table without a header in Markdown](https://stackoverflow.com/questions/17536216/create-a-table-without-a-header-in-markdown))
+
+### Convert CSV To HTML
+
+Of course it is possible to convert a CSV to HTML as well
+
+```
+freemarker-cli \
+ -PCSV_SOURCE_FORMAT=DEFAULT \
+ -t templates/csv/html/transform.ftl \
+ https://raw.githubusercontent.com/apache/freemarker-generator/master/freemarker-generator-cli/examples/data/csv/contract.csv 
+```  
+
+
+
+
diff --git a/freemarker-generator-cli/src/site/markdown/cli/usage/transforming-directories.md b/freemarker-generator-cli/src/site/markdown/cli/usage/transforming-directories.md
index de95e22..412a057 100644
--- a/freemarker-generator-cli/src/site/markdown/cli/usage/transforming-directories.md
+++ b/freemarker-generator-cli/src/site/markdown/cli/usage/transforming-directories.md
@@ -4,8 +4,8 @@
 
 * Transform an input directory recursively into an output directory
 * If a template has a ".ftl" extension this extension will be removed after processing
-* Only a single directory is support
-* Currently no inclusion / exclusion patterns for templates are supported
+* Only a single directory is supported (for now)
+* Currently no inclusion / exclusion patterns for templates are supported (for now)
 
 The following sample files are used
 
diff --git a/freemarker-generator-cli/src/site/markdown/cli/tools/dataframe.md b/freemarker-generator-cli/src/site/markdown/cli/usage/using-dataframes.md
similarity index 99%
rename from freemarker-generator-cli/src/site/markdown/cli/tools/dataframe.md
rename to freemarker-generator-cli/src/site/markdown/cli/usage/using-dataframes.md
index c8daa5d..6a263ea 100644
--- a/freemarker-generator-cli/src/site/markdown/cli/tools/dataframe.md
+++ b/freemarker-generator-cli/src/site/markdown/cli/usage/using-dataframes.md
@@ -1,8 +1,8 @@
-## DataFrameTool
+## DataFrames
 
-The `DataFrameTool` uses [nRo/DataFrame](https://github.com/nRo/DataFrame) to convert tabular data into a `DataFrame`.
+A `DataFrame` allows declarative filtering and transformation of tabular data, i.e. less code to write. 
 
-A `DataFrame` allows declarative filtering and transformation of tabular data, i.e. less code to write.
+The `DataFrameTool` uses [nRo/DataFrame](https://github.com/nRo/DataFrame) to convert tabular data into a `DataFrame`.
 
 Currently the following sources are supported
 
diff --git a/freemarker-generator-cli/src/site/markdown/index.md b/freemarker-generator-cli/src/site/markdown/index.md
index d4526e9..9a584b4 100644
--- a/freemarker-generator-cli/src/site/markdown/index.md
+++ b/freemarker-generator-cli/src/site/markdown/index.md
@@ -1,21 +1,31 @@
 ## FreeMarker Generator CLI
 
+`Apache FreeMarker CLI` is a command-line interface for [Apache FreeMarker](https://freemarker.apache.org/) 
+
+* Requires JDK 1.8+ on Linux, Mac OSX and Windows
+* Use stdin, files and URLs to load data and templates 
+* Reads a variety of structured data formats such as access logs, CSV, Excel, JSON, HTML, YAML, XML
+* Provides JSONPath and DataFrames for advanced data manipulation
+* Transform a directory with a single command-line invocation
+* Made for the heavy lifting of data by using lazy-loading and streaming 
+
 ### Concepts
 
 * [Named URIs](cli/concepts/named-uris.html)
 * [Data Sources](cli/concepts/data-sources.html)
 * [Data Models](cli/concepts/data-models.html)
-* [User-Supplied Parameters](cli/concepts/user-parameters.html)
+* [Passing Configuration Data](cli/concepts/passing-data.html)
 * [Template Loading](cli/concepts/template-loading.html)
-* [Template Includes](cli/concepts/template-includes.html)
 * [Transformation](cli/concepts/transformation.html)
-
-### Working With Tools
-
-* [Overview](cli/tools/overview.html)
-* [DataFrameTool](cli/tools/dataframe.html)
+* [Tools](cli/concepts/tools.html)
 
 ### Usage
 
-* [CLI Configuration](cli/usage/cli-configuration.html)
+* [CLI Examples](https://github.com/apache/freemarker-generator/blob/master/freemarker-generator-cli/README.md)
 * [Transforming Directories](cli/usage/transforming-directories.html)
+* [Using DataFrames](cli/usage/using-dataframes.html)
+* [Transforming CSV](cli/usage/transforming-csv.html)
+
+### Advanced Topics
+
+* [FreeMarker CLI Configuration](cli/usage/cli-configuration.html)
diff --git a/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/ManualTest.java b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/ManualTest.java
index 98d1673..e4c172c 100644
--- a/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/ManualTest.java
+++ b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/ManualTest.java
@@ -25,8 +25,8 @@ public class ManualTest {
 
     private static final String SPACE = " ";
     // private static final String CMD = "-PCSV_SOURCE_FORMAT=DATAFRAME -t examples/templates/dataframe/example.ftl https://raw.githubusercontent.com/nRo/DataFrame/master/src/test/resources/users.csv";
-    // private static final String CMD = "-PCSV_SOURCE_WITH_HEADER=true -PCSV_SOURCE_FORMAT=DEFAULT -PCSV_TARGET_FORMAT=EXCEL -t templates/csv/md/transform.ftl examples/data/csv/contract.csv";
-    private static final String CMD = "-t examples/templates/json/dataframe/github-users.ftl examples/data/json/github-users.json";
+    private static final String CMD = "-PCSV_SOURCE_WITH_HEADER=false -PCSV_SOURCE_FORMAT=DEFAULT -PCSV_TARGET_FORMAT=EXCEL -PCSV_TARGET_WITH_HEADER=true -t templates/csv/csv/transform.ftl examples/data/csv/contract.csv";
+    // private static final String CMD = "-t examples/templates/json/dataframe/github-users.ftl examples/data/json/github-users.json";
 
 
     public static void main(String[] args) {
diff --git a/freemarker-generator-cli/templates/csv/csv/transform.ftl b/freemarker-generator-cli/templates/csv/csv/transform.ftl
index 656131d..ef8cf26 100644
--- a/freemarker-generator-cli/templates/csv/csv/transform.ftl
+++ b/freemarker-generator-cli/templates/csv/csv/transform.ftl
@@ -18,7 +18,12 @@
 <#import "/templates/lib/commons-csv.ftl" as csv />
 <#assign dataSource = DataSources.get(0)>
 <#assign csvParser = CSVTool.parse(dataSource, csv.sourceFormat())>
-<#assign csvPrinter = CSVTool.printer(csv.targetFormat())>
+<#assign csvTargetFormat = csv.targetFormat()>
+<#assign csvPrinter = CSVTool.printer(csvTargetFormat)>
+<#assign csvHeaders = (csvParser.getHeaderMap()!{})?keys>
+<#if csvHeaders?has_content && csvTargetFormat.getSkipHeaderRecord()>
+    ${csvPrinter.printRecord(csvHeaders)}<#t>
+</#if>
 <#list csvParser.iterator() as record>
     ${csvPrinter.printRecord(record)}<#t>
 </#list>
\ No newline at end of file
diff --git a/freemarker-generator-cli/templates/info.ftl b/freemarker-generator-cli/templates/info.ftl
index 838ac29..11275b6 100644
--- a/freemarker-generator-cli/templates/info.ftl
+++ b/freemarker-generator-cli/templates/info.ftl
@@ -25,7 +25,7 @@ Timestamp              : ${.now}
 Output encoding        : ${.output_encoding}
 Output format          : ${.output_format}
 
-FreeMarker CLI Template Directories
+FreeMarker CLI Template Loader Directories
 ------------------------------------------------------------------------------
 <#list SystemTool.getTemplateDirectories() as directory>
 [#${directory?counter}] ${directory}
diff --git a/freemarker-generator-cli/templates/lib/commons-csv.ftl b/freemarker-generator-cli/templates/lib/commons-csv.ftl
index 4082fa8..4e3c771 100644
--- a/freemarker-generator-cli/templates/lib/commons-csv.ftl
+++ b/freemarker-generator-cli/templates/lib/commons-csv.ftl
@@ -27,10 +27,10 @@
 <#function sourceFormat>
     <#assign format = CSVTool.formats[CSV_SOURCE_FORMAT!"DEFAULT"]>
     <#assign delimiter = CSVTool.toDelimiter(CSV_SOURCE_DELIMITER!format.getDelimiter())>
-    <#assign withHeader = CSV_SOURCE_WITH_HEADER!"false">
+    <#assign withHeader = CSV_SOURCE_WITH_HEADER!"true">
     <#assign format = format.withDelimiter(delimiter)>
     <#if withHeader?boolean>
-        <#assign format = format.withHeader()>
+        <#assign format = format.withFirstRecordAsHeader()>
     </#if>
     <#return format>
 </#function>
@@ -46,10 +46,10 @@
 <#function targetFormat>
     <#assign format = CSVTool.formats[CSV_TARGET_FORMAT!"DEFAULT"]>
     <#assign delimiter = CSVTool.toDelimiter(CSV_TARGET_DELIMITER!format.getDelimiter())>
-    <#assign withHeader = CSV_TARGET_WITH_HEADER!"false">
+    <#assign withHeader = CSV_TARGET_WITH_HEADER!"true">
     <#assign format = format.withDelimiter(delimiter)>
     <#if withHeader?boolean>
-        <#assign format = format.withHeader>
+        <#assign format = format.withFirstRecordAsHeader()>
     </#if>
     <#return format>
 </#function>
diff --git a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/commonscsv/CommonsCSVTool.java b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/commonscsv/CommonsCSVTool.java
index 7d2eab6..157e04a 100644
--- a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/commonscsv/CommonsCSVTool.java
+++ b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/commonscsv/CommonsCSVTool.java
@@ -22,6 +22,7 @@ import org.apache.commons.csv.CSVRecord;
 import org.apache.commons.io.input.BOMInputStream;
 import org.apache.freemarker.generator.base.datasource.DataSource;
 import org.apache.freemarker.generator.base.util.StringUtils;
+import org.apache.freemarker.generator.tools.commonscsv.impl.CommonsCSVPrinterFacade;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -238,7 +239,7 @@ public class CommonsCSVTool {
     private static Map<String, CSVFormat> createCSVFormats() {
         final Map<String, CSVFormat> result = new HashMap<>();
         result.put("DEFAULT", CSVFormat.DEFAULT);
-        result.put("DATAFRAME", CSVFormat.DEFAULT.withDelimiter(';').withFirstRecordAsHeader());
+        result.put("DATAFRAME", CSVFormat.RFC4180.withDelimiter(';').withFirstRecordAsHeader());
         result.put("EXCEL", CSVFormat.EXCEL);
         result.put("INFORMIX_UNLOAD", CSVFormat.INFORMIX_UNLOAD);
         result.put("INFORMIX_UNLOAD_CSV", CSVFormat.INFORMIX_UNLOAD_CSV);
diff --git a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/commonscsv/CommonsCSVPrinterFacade.java b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/commonscsv/impl/CommonsCSVPrinterFacade.java
similarity index 97%
rename from freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/commonscsv/CommonsCSVPrinterFacade.java
rename to freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/commonscsv/impl/CommonsCSVPrinterFacade.java
index b8c0574..c8e8ac5 100644
--- a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/commonscsv/CommonsCSVPrinterFacade.java
+++ b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/commonscsv/impl/CommonsCSVPrinterFacade.java
@@ -1,4 +1,4 @@
-package org.apache.freemarker.generator.tools.commonscsv;
+package org.apache.freemarker.generator.tools.commonscsv.impl;
 
 import org.apache.commons.csv.CSVFormat;
 import org.apache.commons.csv.CSVPrinter;
diff --git a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/DataFrameTool.java b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/DataFrameTool.java
index bef1b7a..bdad38e 100644
--- a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/DataFrameTool.java
+++ b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/DataFrameTool.java
@@ -23,9 +23,9 @@ import de.unknownreality.dataframe.sort.SortColumn.Direction;
 import de.unknownreality.dataframe.transform.ColumnDataFrameTransform;
 import de.unknownreality.dataframe.transform.CountTransformer;
 import org.apache.commons.csv.CSVParser;
-import org.apache.freemarker.generator.tools.dataframe.converter.CSVConverter;
-import org.apache.freemarker.generator.tools.dataframe.converter.ListConverter;
-import org.apache.freemarker.generator.tools.dataframe.converter.MapConverter;
+import org.apache.freemarker.generator.tools.dataframe.impl.CSVConverter;
+import org.apache.freemarker.generator.tools.dataframe.impl.ListConverter;
+import org.apache.freemarker.generator.tools.dataframe.impl.MapConverter;
 
 import java.io.StringWriter;
 import java.util.Collection;
diff --git a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/converter/CSVConverter.java b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/impl/CSVConverter.java
similarity index 97%
rename from freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/converter/CSVConverter.java
rename to freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/impl/CSVConverter.java
index 055b508..5745c35 100644
--- a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/converter/CSVConverter.java
+++ b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/impl/CSVConverter.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.freemarker.generator.tools.dataframe.converter;
+package org.apache.freemarker.generator.tools.dataframe.impl;
 
 import de.unknownreality.dataframe.DataFrame;
 import de.unknownreality.dataframe.DataFrameBuilder;
diff --git a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/converter/ConverterUtils.java b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/impl/ConverterUtils.java
similarity index 98%
rename from freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/converter/ConverterUtils.java
rename to freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/impl/ConverterUtils.java
index 5237f52..a600031 100644
--- a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/converter/ConverterUtils.java
+++ b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/impl/ConverterUtils.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.freemarker.generator.tools.dataframe.converter;
+package org.apache.freemarker.generator.tools.dataframe.impl;
 
 import de.unknownreality.dataframe.DataFrame;
 import de.unknownreality.dataframe.DataFrameBuilder;
diff --git a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/converter/ListConverter.java b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/impl/ListConverter.java
similarity index 95%
rename from freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/converter/ListConverter.java
rename to freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/impl/ListConverter.java
index ecf891a..4c17fd6 100644
--- a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/converter/ListConverter.java
+++ b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/impl/ListConverter.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.freemarker.generator.tools.dataframe.converter;
+package org.apache.freemarker.generator.tools.dataframe.impl;
 
 import de.unknownreality.dataframe.DataFrame;
 import org.apache.freemarker.generator.base.table.Table;
diff --git a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/converter/MapConverter.java b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/impl/MapConverter.java
similarity index 92%
rename from freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/converter/MapConverter.java
rename to freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/impl/MapConverter.java
index d8906c1..bc1a287 100644
--- a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/converter/MapConverter.java
+++ b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/dataframe/impl/MapConverter.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.freemarker.generator.tools.dataframe.converter;
+package org.apache.freemarker.generator.tools.dataframe.impl;
 
 import de.unknownreality.dataframe.DataFrame;
 import org.apache.freemarker.generator.base.table.Table;
@@ -22,8 +22,6 @@ import org.apache.freemarker.generator.base.table.Table;
 import java.util.Collection;
 import java.util.Map;
 
-import static java.util.Collections.singletonList;
-
 public class MapConverter {
 
     /**
diff --git a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/freemarker/FreeMarkerTool.java b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/freemarker/FreeMarkerTool.java
index 45b43e6..217aa8f 100644
--- a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/freemarker/FreeMarkerTool.java
+++ b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/freemarker/FreeMarkerTool.java
@@ -22,11 +22,19 @@ import freemarker.template.Configuration;
 import freemarker.template.TemplateHashModel;
 import freemarker.template.utility.ObjectConstructor;
 
+/**
+ * Exposes useful Apache FreeMarker classes for advanced FTL usage.
+ */
 public class FreeMarkerTool {
 
-    private BeansWrapper beansWrapper;
-    private ObjectConstructor objectConstructor;
+    private volatile BeansWrapper beansWrapper;
+    private volatile ObjectConstructor objectConstructor;
 
+    /**
+     * See <a href="https://freemarker.apache.org/docs/api/freemarker/template/utility/ObjectConstructor.html">FreeMarker ObjectConstructor</a>.
+     *
+     * @return ObjectConstructor
+     */
     public synchronized ObjectConstructor getObjectConstructor() {
         if (objectConstructor == null) {
             objectConstructor = new ObjectConstructor();
@@ -34,6 +42,11 @@ public class FreeMarkerTool {
         return objectConstructor;
     }
 
+    /**
+     * See <a href="https://freemarker.apache.org/docs/api/freemarker/ext/beans/BeansWrapper.html">FreeMarker BeansWrapper</a>.
+     *
+     * @return BeansWrapper
+     */
     public synchronized BeansWrapper getBeansWrapper() {
         if (beansWrapper == null) {
             beansWrapper = new BeansWrapperBuilder(Configuration.VERSION_2_3_30).build();
@@ -51,7 +64,7 @@ public class FreeMarkerTool {
 
     @Override
     public String toString() {
-        return "Expose useful Apache FreeMarker classes";
+        return "Expose advanced Apache FreeMarker classes";
     }
 }
 
diff --git a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/grok/GrokTool.java b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/grok/GrokTool.java
index 984d22c..0beab72 100644
--- a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/grok/GrokTool.java
+++ b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/grok/GrokTool.java
@@ -18,6 +18,7 @@ package org.apache.freemarker.generator.tools.grok;
 
 import io.krakens.grok.api.Grok;
 import io.krakens.grok.api.GrokCompiler;
+import org.apache.freemarker.generator.tools.grok.impl.GrokWrapper;
 
 public class GrokTool {
 
diff --git a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/grok/GrokWrapper.java b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/grok/impl/GrokWrapper.java
similarity index 95%
rename from freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/grok/GrokWrapper.java
rename to freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/grok/impl/GrokWrapper.java
index 7a6931e..626a94f 100644
--- a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/grok/GrokWrapper.java
+++ b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/grok/impl/GrokWrapper.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.freemarker.generator.tools.grok;
+package org.apache.freemarker.generator.tools.grok.impl;
 
 import io.krakens.grok.api.Grok;
 import org.apache.freemarker.generator.base.util.StringUtils;
diff --git a/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/commonscsv/CommonsCSVToolTest.java b/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/commonscsv/CommonsCSVToolTest.java
index 29f8e0e..472e378 100644
--- a/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/commonscsv/CommonsCSVToolTest.java
+++ b/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/commonscsv/CommonsCSVToolTest.java
@@ -21,6 +21,7 @@ import org.apache.commons.csv.CSVParser;
 import org.apache.commons.csv.CSVRecord;
 import org.apache.freemarker.generator.base.datasource.DataSource;
 import org.apache.freemarker.generator.base.datasource.DataSourceFactory;
+import org.apache.freemarker.generator.tools.commonscsv.impl.CommonsCSVPrinterFacade;
 import org.junit.Test;
 
 import java.io.File;
diff --git a/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/grok/GrokToolTest.java b/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/grok/GrokToolTest.java
index 2bf21dc..30c0ed7 100644
--- a/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/grok/GrokToolTest.java
+++ b/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/grok/GrokToolTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.freemarker.generator.tools.grok;
 
+import org.apache.freemarker.generator.tools.grok.impl.GrokWrapper;
 import org.junit.Test;
 
 import java.util.Map;
diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md
index 455ebb0..bf0072c 100644
--- a/src/site/markdown/index.md
+++ b/src/site/markdown/index.md
@@ -2,7 +2,5 @@ The Apache FreeMarker Generator projects provides additional tools to generate t
 
 | Name                                                          | Description                                                       |
 | ------------------------------------------------------------- | ----------------------------------------------------------------- |
-| [Base](freemarker-generator-base/index.html)                  | Common functionality independent from Apache FreeMarker           |
-| [Tools](freemarker-generator-tools/index.html)                | Data source processing tools for Apache FreeMarker Generator      |
 | [CLI](freemarker-generator-cli/index.html)                    | Command-line client for Apache FreeMarker                         |
 | [Maven Plugin](freemarker-generator-maven-plugin/index.html)  | Maven plugin for Apache FreeMarker                                |
\ No newline at end of file
diff --git a/travis.sh b/travis.sh
index f76ae9d..1c55d1e 100755
--- a/travis.sh
+++ b/travis.sh
@@ -1,6 +1,24 @@
 #!/bin/sh
-mvn clean install
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Simulate the Travis build locally
+mvn clean install site site:stage
 cd ./freemarker-generator-cli
 sh ./run-examples.sh
 cd ../freemarker-generator-maven-plugin-sample
-mvn clean package
+mvn clean package
\ No newline at end of file