Repository: jtablesaw/tablesaw
Pull request #637 (2019-08-25 22:18:54)

Compile Tutorial docs.
- [x] Tick to sign-off your agreement to the [Developer Certificate of Origin (DCO) 1.1](https://developercertificate.org)

## Description

This not fully baked, but getting there. #457

* Creates a docs module (so it can contain compiled code)
* Add a plugin with similar functionality to paradox to inject snippets into markdown. 
* Adds an add hoc class that saves the output of the compiled snippets so they can be used in the docs. (E.G. the text output of table.first(10))
* Rewrites the tornado tutorial using using the new tools. (It was not even close to compiling)

For more information:

* See the README of https://github.com/ryancerf/choss-maven-plugin

* Read the README in the docs subdirectory.

## Testing

The plugin is well tested.

benmccann: This looks pretty cool!
ryancerf: > This looks pretty cool!

Thanks for the idea!

Patch:
diff --git a/.gitignore b/.gitignore
index 76669a2b..629b42e5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,9 @@
 target/
 
+#docs
+/docs/dist/*
+/docs/output/*
+
 databases/
 
 data/filtered_bus_stops.csv
diff --git a/core/src/main/java/tech/tablesaw/api/BooleanColumn.java b/core/src/main/java/tech/tablesaw/api/BooleanColumn.java
index 6703940a..55a65fdd 100644
--- a/core/src/main/java/tech/tablesaw/api/BooleanColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/BooleanColumn.java
@@ -39,6 +39,7 @@ import java.util.function.BiPredicate;
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
+import java.util.stream.Stream;
 import tech.tablesaw.columns.AbstractColumn;
 import tech.tablesaw.columns.AbstractColumnParser;
 import tech.tablesaw.columns.Column;
@@ -120,7 +121,6 @@ public class BooleanColumn extends AbstractColumn<Boolean>
   }
 
   public static BooleanColumn create(String name, boolean[] values) {
-
     BooleanColumn column = create(name, values.length);
     int r = 0;
     for (boolean b : values) {
@@ -138,14 +138,20 @@ public class BooleanColumn extends AbstractColumn<Boolean>
     return column;
   }
 
-  public static BooleanColumn create(String name, Boolean[] objects) {
+  public static BooleanColumn create(String name, Boolean[] arr) {
     BooleanColumn column = create(name);
-    for (Boolean b : objects) {
-      column.append(b);
+    for (Boolean val : arr) {
+      column.append(val);
     }
     return column;
   }
 
+  public static BooleanColumn create(String name, Stream<Boolean> stream) {
+    BooleanColumn column = create(name);
+    stream.forEach(val -> column.append(val));
+    return column;
+  }
+
   @Override
   public BooleanColumn setName(String name) {
     return (BooleanColumn) super.setName(name);
diff --git a/core/src/main/java/tech/tablesaw/api/DateColumn.java b/core/src/main/java/tech/tablesaw/api/DateColumn.java
index d9b811b7..cc59b924 100644
--- a/core/src/main/java/tech/tablesaw/api/DateColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/DateColumn.java
@@ -35,6 +35,7 @@ import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
+import java.util.stream.Stream;
 import tech.tablesaw.columns.AbstractColumn;
 import tech.tablesaw.columns.AbstractColumnParser;
 import tech.tablesaw.columns.Column;
@@ -95,6 +96,12 @@ public class DateColumn extends AbstractColumn<LocalDate>
     return column;
   }
 
+  public static DateColumn create(String name, Stream<LocalDate> stream) {
+    DateColumn column = create(name);
+    stream.forEach(val -> column.append(val));
+    return column;
+  }
+
   private DateColumn(String name, IntArrayList data) {
     super(DateColumnType.instance(), name);
     this.data = data;
diff --git a/core/src/main/java/tech/tablesaw/api/DateTimeColumn.java b/core/src/main/java/tech/tablesaw/api/DateTimeColumn.java
index 2a0f5fcd..e5c4d901 100644
--- a/core/src/main/java/tech/tablesaw/api/DateTimeColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/DateTimeColumn.java
@@ -41,6 +41,7 @@ import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
+import java.util.stream.Stream;
 import tech.tablesaw.columns.AbstractColumn;
 import tech.tablesaw.columns.AbstractColumnParser;
 import tech.tablesaw.columns.Column;
@@ -98,6 +99,12 @@ public class DateTimeColumn extends AbstractColumn<LocalDateTime>
     return column;
   }
 
+  public static DateTimeColumn create(String name, Stream<LocalDateTime> stream) {
+    DateTimeColumn column = create(name);
+    stream.forEach(val -> column.append(val));
+    return column;
+  }
+
   @Override
   public DateTimeColumn plus(long amountToAdd, ChronoUnit unit) {
     DateTimeColumn newColumn = emptyCopy();
diff --git a/core/src/main/java/tech/tablesaw/api/DoubleColumn.java b/core/src/main/java/tech/tablesaw/api/DoubleColumn.java
index c25e69bf..f5522184 100644
--- a/core/src/main/java/tech/tablesaw/api/DoubleColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/DoubleColumn.java
@@ -18,6 +18,7 @@ import java.util.function.DoublePredicate;
 import java.util.function.DoubleSupplier;
 import java.util.function.Function;
 import java.util.function.Predicate;
+import java.util.stream.DoubleStream;
 import tech.tablesaw.columns.AbstractColumnParser;
 import tech.tablesaw.columns.Column;
 import tech.tablesaw.columns.numbers.DoubleColumnType;
@@ -36,7 +37,7 @@ public class DoubleColumn extends NumberColumn<Double> implements NumberFillers<
 
   private final DoubleArrayList data;
 
-  protected DoubleColumn(final String name, final DoubleArrayList data) {
+  protected DoubleColumn(String name, DoubleArrayList data) {
     super(DoubleColumnType.instance(), name);
     setPrintFormatter(NumberColumnFormatter.floatingPointDefault());
     this.data = data;
@@ -47,7 +48,7 @@ public class DoubleColumn extends NumberColumn<Double> implements NumberFillers<
   }
 
   @Override
-  public String getString(final int row) {
+  public String getString(int row) {
     final double value = getDouble(row);
     if (DoubleColumnType.isMissingValue(value)) {
       return "";
@@ -70,21 +71,21 @@ public class DoubleColumn extends NumberColumn<Double> implements NumberFillers<
     return this;
   }
 
-  protected DoubleColumn(final String name) {
+  protected DoubleColumn(String name) {
     super(DoubleColumnType.instance(), name);
     setPrintFormatter(NumberColumnFormatter.floatingPointDefault());
     this.data = new DoubleArrayList(DEFAULT_ARRAY_SIZE);
   }
 
-  public static DoubleColumn create(final String name, final double[] arr) {
+  public static DoubleColumn create(String name, double[] arr) {
     return new DoubleColumn(name, new DoubleArrayList(arr));
   }
 
-  public static DoubleColumn create(final String name) {
+  public static DoubleColumn create(String name) {
     return new DoubleColumn(name);
   }
 
-  public static DoubleColumn create(final String name, final float[] arr) {
+  public static DoubleColumn create(String name, float[] arr) {
     final double[] doubles = new double[arr.length];
     for (int i = 0; i < arr.length; i++) {
       doubles[i] = arr[i];
@@ -92,7 +93,7 @@ public class DoubleColumn extends NumberColumn<Double> implements NumberFillers<
     return new DoubleColumn(name, new DoubleArrayList(doubles));
   }
 
-  public static DoubleColumn create(final String name, final int[] arr) {
+  public static DoubleColumn create(String name, int[] arr) {
     final double[] doubles = new double[arr.length];
     for (int i = 0; i < arr.length; i++) {
       doubles[i] = arr[i];
@@ -100,7 +101,7 @@ public class DoubleColumn extends NumberColumn<Double> implements NumberFillers<
     return new DoubleColumn(name, new DoubleArrayList(doubles));
   }
 
-  public static DoubleColumn create(final String name, final long[] arr) {
+  public static DoubleColumn create(String name, long[] arr) {
     final double[] doubles = new double[arr.length];
     for (int i = 0; i < arr.length; i++) {
       doubles[i] = arr[i];
@@ -108,7 +109,7 @@ public class DoubleColumn extends NumberColumn<Double> implements NumberFillers<
     return new DoubleColumn(name, new DoubleArrayList(doubles));
   }
 
-  public static DoubleColumn create(final String name, final List<Number> numberList) {
+  public static DoubleColumn create(String name, List<Number> numberList) {
     DoubleColumn newColumn = new DoubleColumn(name, new DoubleArrayList(0));
     for (Number number : numberList) {
       newColumn.append(number);
@@ -116,7 +117,7 @@ public class DoubleColumn extends NumberColumn<Double> implements NumberFillers<
     return newColumn;
   }
 
-  public static DoubleColumn create(final String name, final Number[] numbers) {
+  public static DoubleColumn create(String name, Number[] numbers) {
     DoubleColumn newColumn = new DoubleColumn(name, new DoubleArrayList(0));
     for (Number number : numbers) {
       newColumn.append(number);
@@ -124,7 +125,7 @@ public class DoubleColumn extends NumberColumn<Double> implements NumberFillers<
     return newColumn;
   }
 
-  public static DoubleColumn create(final String name, final int initialSize) {
+  public static DoubleColumn create(String name, int initialSize) {
     DoubleColumn column = new DoubleColumn(name);
     for (int i = 0; i < initialSize; i++) {
       column.appendMissing();
@@ -132,13 +133,19 @@ public class DoubleColumn extends NumberColumn<Double> implements NumberFillers<
     return column;
   }
 
+  public static DoubleColumn create(String name, DoubleStream stream) {
+    DoubleArrayList list = new DoubleArrayList();
+    stream.forEach(val -> list.add(val));
+    return new DoubleColumn(name, list);
+  }
+
   @Override
-  public DoubleColumn createCol(final String name, final int initialSize) {
+  public DoubleColumn createCol(String name, int initialSize) {
     return create(name, initialSize);
   }
 
   @Override
-  public DoubleColumn createCol(final String name) {
+  public DoubleColumn createCol(String name) {
     return create(name);
   }
 
@@ -148,7 +155,7 @@ public class DoubleColumn extends NumberColumn<Double> implements NumberFillers<
   }
 
   @Override
-  public DoubleColumn subset(final int[] rows) {
+  public DoubleColumn subset(int[] rows) {
     final DoubleColumn c = this.emptyCopy();
     for (final int row : rows) {
       c.append(getDouble(row));
diff --git a/core/src/main/java/tech/tablesaw/api/FloatColumn.java b/core/src/main/java/tech/tablesaw/api/FloatColumn.java
index 900e3da1..0ad5b55f 100644
--- a/core/src/main/java/tech/tablesaw/api/FloatColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/FloatColumn.java
@@ -13,6 +13,7 @@ import java.util.Iterator;
 import java.util.function.DoublePredicate;
 import java.util.function.Function;
 import java.util.function.Predicate;
+import java.util.stream.Stream;
 import tech.tablesaw.columns.AbstractColumnParser;
 import tech.tablesaw.columns.Column;
 import tech.tablesaw.columns.numbers.FloatColumnType;
@@ -28,14 +29,14 @@ public class FloatColumn extends NumberColumn<Float> {
 
   private final FloatArrayList data;
 
-  private FloatColumn(final String name, FloatArrayList data) {
+  private FloatColumn(String name, FloatArrayList data) {
     super(FloatColumnType.instance(), name);
     setPrintFormatter(NumberColumnFormatter.floatingPointDefault());
     this.data = data;
   }
 
   @Override
-  public String getString(final int row) {
+  public String getString(int row) {
     final float value = getFloat(row);
     if (FloatColumnType.isMissingValue(value)) {
       return "";
@@ -43,15 +44,15 @@ public class FloatColumn extends NumberColumn<Float> {
     return String.valueOf(getPrintFormatter().format(value));
   }
 
-  public static FloatColumn create(final String name) {
+  public static FloatColumn create(String name) {
     return new FloatColumn(name, new FloatArrayList());
   }
 
-  public static FloatColumn create(final String name, final float[] arr) {
+  public static FloatColumn create(String name, float[] arr) {
     return new FloatColumn(name, new FloatArrayList(arr));
   }
 
-  public static FloatColumn create(final String name, final int initialSize) {
+  public static FloatColumn create(String name, int initialSize) {
     FloatColumn column = new FloatColumn(name, new FloatArrayList(initialSize));
     for (int i = 0; i < initialSize; i++) {
       column.appendMissing();
@@ -59,13 +60,27 @@ public class FloatColumn extends NumberColumn<Float> {
     return column;
   }
 
+  public static FloatColumn create(String name, Float[] arr) {
+    FloatColumn column = create(name);
+    for (Float val : arr) {
+      column.append(val);
+    }
+    return column;
+  }
+
+  public static FloatColumn create(String name, Stream<Float> stream) {
+    FloatColumn column = create(name);
+    stream.forEach(val -> column.append(val));
+    return column;
+  }
+
   @Override
-  public FloatColumn createCol(final String name, final int initialSize) {
+  public FloatColumn createCol(String name, int initialSize) {
     return create(name, initialSize);
   }
 
   @Override
-  public FloatColumn createCol(final String name) {
+  public FloatColumn createCol(String name) {
     return create(name);
   }
 
@@ -79,7 +94,7 @@ public class FloatColumn extends NumberColumn<Float> {
   }
 
   @Override
-  public FloatColumn subset(final int[] rows) {
+  public FloatColumn subset(int[] rows) {
     final FloatColumn c = this.emptyCopy();
     for (final int row : rows) {
       c.append(getFloat(row));
diff --git a/core/src/main/java/tech/tablesaw/api/InstantColumn.java b/core/src/main/java/tech/tablesaw/api/InstantColumn.java
index 0c7d391b..0c29a6c5 100644
--- a/core/src/main/java/tech/tablesaw/api/InstantColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/InstantColumn.java
@@ -43,6 +43,7 @@ import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
+import java.util.stream.Stream;
 import tech.tablesaw.columns.AbstractColumn;
 import tech.tablesaw.columns.AbstractColumnParser;
 import tech.tablesaw.columns.Column;
@@ -108,6 +109,12 @@ public class InstantColumn extends AbstractColumn<Instant>
     return column;
   }
 
+  public static InstantColumn create(String name, Stream<Instant> stream) {
+    InstantColumn column = create(name);
+    stream.forEach(val -> column.append(val));
+    return column;
+  }
+
   public static boolean valueIsMissing(long value) {
     return InstantColumnType.isMissingValue(value);
   }
diff --git a/core/src/main/java/tech/tablesaw/api/IntColumn.java b/core/src/main/java/tech/tablesaw/api/IntColumn.java
index 7e0b6650..46b66535 100644
--- a/core/src/main/java/tech/tablesaw/api/IntColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/IntColumn.java
@@ -13,6 +13,7 @@ import java.util.Iterator;
 import java.util.function.DoublePredicate;
 import java.util.function.Function;
 import java.util.function.Predicate;
+import java.util.stream.IntStream;
 import tech.tablesaw.columns.AbstractColumnParser;
 import tech.tablesaw.columns.Column;
 import tech.tablesaw.columns.numbers.DoubleColumnType;
@@ -49,7 +50,7 @@ public class IntColumn extends NumberColumn<Integer> implements CategoricalColum
     return newColumn;
   }
 
-  public static IntColumn create(final String name, final int initialSize) {
+  public static IntColumn create(String name, int initialSize) {
     IntColumn column = new IntColumn(name, new IntArrayList(initialSize));
     for (int i = 0; i < initialSize; i++) {
       column.appendMissing();
@@ -57,13 +58,19 @@ public class IntColumn extends NumberColumn<Integer> implements CategoricalColum
     return column;
   }
 
+  public static IntColumn create(String name, IntStream stream) {
+    IntArrayList list = new IntArrayList();
+    stream.forEach(val -> list.add(val));
+    return new IntColumn(name, list);
+  }
+
   @Override
-  public IntColumn createCol(final String name, final int initialSize) {
+  public IntColumn createCol(String name, int initialSize) {
     return create(name, initialSize);
   }
 
   @Override
-  public IntColumn createCol(final String name) {
+  public IntColumn createCol(String name) {
     return create(name);
   }
 
diff --git a/core/src/main/java/tech/tablesaw/api/LongColumn.java b/core/src/main/java/tech/tablesaw/api/LongColumn.java
index f2e1e26e..32dc9dec 100644
--- a/core/src/main/java/tech/tablesaw/api/LongColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/LongColumn.java
@@ -15,6 +15,7 @@ import java.util.Iterator;
 import java.util.function.DoublePredicate;
 import java.util.function.Function;
 import java.util.function.Predicate;
+import java.util.stream.LongStream;
 import tech.tablesaw.columns.AbstractColumnParser;
 import tech.tablesaw.columns.Column;
 import tech.tablesaw.columns.numbers.DoubleColumnType;
@@ -29,7 +30,7 @@ public class LongColumn extends NumberColumn<Long> implements CategoricalColumn<
 
   private final LongArrayList data;
 
-  private LongColumn(final String name, LongArrayList data) {
+  private LongColumn(String name, LongArrayList data) {
     super(LongColumnType.instance(), name);
     setPrintFormatter(NumberColumnFormatter.ints());
     this.data = data;
@@ -39,11 +40,11 @@ public class LongColumn extends NumberColumn<Long> implements CategoricalColumn<
     return new LongColumn(name, new LongArrayList());
   }
 
-  public static LongColumn create(final String name, final long[] arr) {
+  public static LongColumn create(String name, long[] arr) {
     return new LongColumn(name, new LongArrayList(arr));
   }
 
-  public static LongColumn create(final String name, final int initialSize) {
+  public static LongColumn create(String name, int initialSize) {
     LongColumn column = new LongColumn(name, new LongArrayList(initialSize));
     for (int i = 0; i < initialSize; i++) {
       column.appendMissing();
@@ -51,13 +52,19 @@ public class LongColumn extends NumberColumn<Long> implements CategoricalColumn<
     return column;
   }
 
+  public static LongColumn create(String name, LongStream stream) {
+    LongArrayList list = new LongArrayList();
+    stream.forEach(val -> list.add(val));
+    return new LongColumn(name, list);
+  }
+
   @Override
-  public LongColumn createCol(final String name, final int initialSize) {
+  public LongColumn createCol(String name, int initialSize) {
     return create(name, initialSize);
   }
 
   @Override
-  public LongColumn createCol(final String name) {
+  public LongColumn createCol(String name) {
     return create(name);
   }
 
diff --git a/core/src/main/java/tech/tablesaw/api/ShortColumn.java b/core/src/main/java/tech/tablesaw/api/ShortColumn.java
index 60805874..613900f9 100644
--- a/core/src/main/java/tech/tablesaw/api/ShortColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/ShortColumn.java
@@ -1,6 +1,7 @@
 package tech.tablesaw.api;
 
 import com.google.common.base.Preconditions;
+import com.google.common.primitives.Shorts;
 import it.unimi.dsi.fastutil.shorts.ShortArrayList;
 import it.unimi.dsi.fastutil.shorts.ShortArrays;
 import it.unimi.dsi.fastutil.shorts.ShortComparator;
@@ -8,11 +9,13 @@ import it.unimi.dsi.fastutil.shorts.ShortListIterator;
 import it.unimi.dsi.fastutil.shorts.ShortOpenHashSet;
 import it.unimi.dsi.fastutil.shorts.ShortSet;
 import java.nio.ByteBuffer;
+import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.function.DoublePredicate;
 import java.util.function.Function;
 import java.util.function.Predicate;
+import java.util.stream.Stream;
 import tech.tablesaw.columns.AbstractColumnParser;
 import tech.tablesaw.columns.Column;
 import tech.tablesaw.columns.numbers.DoubleColumnType;
@@ -49,6 +52,16 @@ public class ShortColumn extends NumberColumn<Short> implements CategoricalColum
     return column;
   }
 
+  public static ShortColumn create(final String name, final Short[] arr) {
+    return new ShortColumn(name, new ShortArrayList(Shorts.toArray(Arrays.asList(arr))));
+  }
+
+  public static ShortColumn create(String name, Stream<Short> stream) {
+    ShortColumn column = create(name);
+    stream.forEach(val -> column.append(val));
+    return column;
+  }
+
   @Override
   public ShortColumn createCol(final String name, final int initialSize) {
     return create(name, initialSize);
diff --git a/core/src/main/java/tech/tablesaw/api/StringColumn.java b/core/src/main/java/tech/tablesaw/api/StringColumn.java
index a36b672c..b8928f92 100644
--- a/core/src/main/java/tech/tablesaw/api/StringColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/StringColumn.java
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Set;
 import java.util.function.Function;
 import java.util.function.Predicate;
+import java.util.stream.Stream;
 import tech.tablesaw.columns.AbstractColumnParser;
 import tech.tablesaw.columns.Column;
 import tech.tablesaw.columns.strings.AbstractStringColumn;
@@ -85,6 +86,12 @@ public class StringColumn extends AbstractStringColumn {
     return column;
   }
 
+  public static StringColumn create(String name, Stream<String> stream) {
+    StringColumn column = create(name);
+    stream.forEach(val -> column.append(val));
+    return column;
+  }
+
   private StringColumn(String name, List<String> strings) {
     super(StringColumnType.instance(), name);
     for (String string : strings) {
diff --git a/core/src/main/java/tech/tablesaw/api/TextColumn.java b/core/src/main/java/tech/tablesaw/api/TextColumn.java
index 359033fb..0c5aa668 100644
--- a/core/src/main/java/tech/tablesaw/api/TextColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/TextColumn.java
@@ -24,6 +24,7 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
+import java.util.stream.Stream;
 import tech.tablesaw.columns.AbstractColumnParser;
 import tech.tablesaw.columns.Column;
 import tech.tablesaw.columns.strings.AbstractStringColumn;
@@ -105,6 +106,12 @@ public class TextColumn extends AbstractStringColumn {
     return new TextColumn(name, strings);
   }
 
+  public static TextColumn create(String name, Stream<String> stream) {
+    TextColumn column = create(name);
+    stream.forEach(val -> column.append(val));
+    return column;
+  }
+
   @Override
   public boolean isMissing(int rowNumber) {
     return get(rowNumber).equals(TextColumnType.missingValueIndicator());
diff --git a/core/src/main/java/tech/tablesaw/api/TimeColumn.java b/core/src/main/java/tech/tablesaw/api/TimeColumn.java
index afb60d46..0c3c8f76 100644
--- a/core/src/main/java/tech/tablesaw/api/TimeColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/TimeColumn.java
@@ -36,6 +36,7 @@ import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
+import java.util.stream.Stream;
 import tech.tablesaw.columns.AbstractColumn;
 import tech.tablesaw.columns.AbstractColumnParser;
 import tech.tablesaw.columns.Column;
@@ -110,6 +111,12 @@ public class TimeColumn extends AbstractColumn<LocalTime>
     return column;
   }
 
+  public static TimeColumn create(String name, Stream<LocalTime> stream) {
+    TimeColumn column = create(name);
+    stream.forEach(val -> column.append(val));
+    return column;
+  }
+
   @Override
   public TimeColumn appendMissing() {
     appendInternal(TimeColumnType.missingValueIndicator());
diff --git a/docs/README.md b/docs/README.md
index 795781cb..587b8499 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,11 +1,29 @@
-# Tablesaw Documentation
+## Compiled Docs
 
-* [The Tornado Tutorial](https://jtablesaw.github.io/tablesaw/tutorial) A short tutorial using Tablesaw to analyze a Tornado dataset.
-* [Getting Started](https://jtablesaw.github.io/tablesaw/gettingstarted)  If you haven't used Tablesaw, or are having trouble 'getting it', you should start here. It covers most everything you need to begin using it productively. 
-* [User Guide](https://jtablesaw.github.io/tablesaw/userguide/toc) An in-depth guide to much of Tablesaw's functionality.
-* [Javadoc](http://www.javadoc.io/doc/tech.tablesaw/tablesaw-core/)
-* [Contributor's Guide](https://jtablesaw.github.io/tablesaw/contributing) We welcome contributions! Here's how. 
-* [Release Notes](https://github.com/jtablesaw/tablesaw/releases)
+There are three important inputs to the docs.
 
-Can't find what you're looking for?
-Ask your questions on the project [Issues page](https://github.com/jtablesaw/tablesaw/issues)
+1) Content files (markdown)
+
+2) src files (java) that hold the compiled code.
+
+3) output of running snippets in the src files. E.G. `table.first(10)`
+
+
+### To update the Docs
+
+1) Navigate to the  `./docs` sub directory (Where POM is located).
+
+2) Runs the src files and save the output snippets to `output/`
+
+    `mvn compile && mvn exec:java`
+
+3) Inject snippets into content files and copy everything the content to `dist/`
+
+    `mvn com.github.ryancerf:choss-maven-plugin:build-docs`
+    
+4) Deploy the docs from `dist/`
+    
+ ### Notes
+ 
+ For more background on injecting snippets see:
+ https://github.com/ryancerf/choss-maven-plugin
diff --git a/docs/main/README.md b/docs/main/README.md
new file mode 100644
index 00000000..795781cb
--- /dev/null
+++ b/docs/main/README.md
@@ -0,0 +1,11 @@
+# Tablesaw Documentation
+
+* [The Tornado Tutorial](https://jtablesaw.github.io/tablesaw/tutorial) A short tutorial using Tablesaw to analyze a Tornado dataset.
+* [Getting Started](https://jtablesaw.github.io/tablesaw/gettingstarted)  If you haven't used Tablesaw, or are having trouble 'getting it', you should start here. It covers most everything you need to begin using it productively. 
+* [User Guide](https://jtablesaw.github.io/tablesaw/userguide/toc) An in-depth guide to much of Tablesaw's functionality.
+* [Javadoc](http://www.javadoc.io/doc/tech.tablesaw/tablesaw-core/)
+* [Contributor's Guide](https://jtablesaw.github.io/tablesaw/contributing) We welcome contributions! Here's how. 
+* [Release Notes](https://github.com/jtablesaw/tablesaw/releases)
+
+Can't find what you're looking for?
+Ask your questions on the project [Issues page](https://github.com/jtablesaw/tablesaw/issues)
diff --git a/docs/_config.yml b/docs/main/_config.yml
similarity index 100%
rename from docs/_config.yml
rename to docs/main/_config.yml
diff --git a/docs/contributing.md b/docs/main/contributing.md
similarity index 100%
rename from docs/contributing.md
rename to docs/main/contributing.md
diff --git a/docs/gettingstarted.md b/docs/main/gettingstarted.md
similarity index 100%
rename from docs/gettingstarted.md
rename to docs/main/gettingstarted.md
diff --git a/docs/main/tutorial.md b/docs/main/tutorial.md
new file mode 100644
index 00000000..54d4fbfc
--- /dev/null
+++ b/docs/main/tutorial.md
@@ -0,0 +1,227 @@
+
+
+# Tablesaw: A brief tutorial
+
+Tablesaw is a large library. We'll use Tablesaw to look at data about Tornadoes. If you haven't already done so,
+we strongly recommend that you read the Getting Started guide, before continuing here. 
+
+## Exploring Tornadoes 
+
+To give a better sense of how Tablesaw works, we’ll use a tornado data set from NOAA. Here’s what we’ll cover:
+
+* Reading and writing CSV files
+* Viewing table metadata
+* Adding and removing columns
+* Printing the first few rows for a peak at the data
+* Sorting
+* Running descriptive stats (mean, min, max, etc.)
+* Performing mapping operations over columns
+* Filtering rows
+* Computing cross-tabs
+
+All the data is in the Tablesaw *data* folder. The code is taken from the TornadoExample test class.
+
+### Read a CSV file
+
+Here we read a csv file of tornado data. Tablesaw infers the column types by sampling the data.
+
+```java
+@@snip [table_read](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+```
+
+**Note:** that the file is addressed relative to the current working directory. You may have to change it for your code. 
+
+### Viewing table metadata
+
+Often, the best way to start is to print the column names for reference:
+
+```java
+@@snip [table_columns](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+
+@@snip [table_columns](./output/tech/tablesaw/docs/Tutorial.txt)
+```
+
+
+The *shape()* method displays the row and column counts:
+
+```java
+@@snip [table_shape](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+
+@@snip [table_shape](./output/tech/tablesaw/docs/Tutorial.txt)
+```
+
+*structure()* shows the index, name and type of each column
+
+```java
+@@snip [table_structure](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+
+@@snip [table_structure](./output/tech/tablesaw/docs/Tutorial.txt)
+```
+
+Like many Tablesaw methods, *structure()* returns a table.  You can then produce a string representation for display.
+For convenience, calling *toString()* on a table invokes *print()*, which produces a string representation of the table
+table. To display the table then, you can simply call. 
+
+```java
+@@snip [print_table](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+```
+
+You can also perform other table operations on it. For example, the code below removes all columns whose type isn’t DOUBLE:
+            
+```java
+@@snip [filter_structure](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+
+@@snip [filter_structure](./output/tech/tablesaw/docs/Tutorial.txt)
+```
+
+
+Of course, that also returned a table. We’ll cover selecting rows in more detail later.
+
+### Previewing data
+
+The *first(n)* method returns a new table containing the first n rows.
+        
+```java
+@@snip [first_n](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+
+@@snip [first_n](./output/tech/tablesaw/docs/Tutorial.txt)
+
+```
+
+### Mapping operations
+
+Mapping operations in Tablesaw take one or more columns as inputs and produce a new column as output. We can map
+arbitrary expressions onto the table, but many common operations are built in. You can, for example, calculate the
+difference in days, weeks, or years between the values in two date columns. The method below extracts the Month name
+from the date column into a new column.
+
+```java
+@@snip [date_col](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+```
+
+Now that you have a new column, you can add it to the table:
+
+```java
+@@snip [add_date_col](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+```
+
+You can remove columns from tables to save memory or reduce clutter:
+
+```java
+@@snip [remove_col](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+```
+
+### Sorting
+
+Now lets sort the table in reverse order by the id column. The negative sign before the name indicates a descending sort.
+
+```java
+@@snip [sort_on](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+```
+### Descriptive statistics
+
+Descriptive statistics are calculated using the summary() method:
+
+```java
+@@snip [summary](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+
+@@snip [summary](./output/tech/tablesaw/docs/Tutorial.txt)
+```
+
+### Filtering
+
+You can write your own methods to filter rows, but it’s easier to use the built-in filter classes as shown below:
+
+```java
+@@snip [filtering](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+
+@@snip [filtering](./output/tech/tablesaw/docs/Tutorial.txt)
+
+```
+The last example above returns a table containing only the columns named in *select()* parameters,rather than all the
+columns in the original.
+
+### Totals and sub-totals
+
+Column metrics can be calculated using methods like *sum()*, *product()*, *mean()*, *max()*, etc.
+
+You can apply those methods to a table, calculating results on one column, grouped by the values in another.
+
+```java
+@@snip [totals](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+
+```
+
+This produces the following table, in which Group represents the Tornado Scale and Median the median injures for that group:
+
+```
+@@snip [totals](./output/tech/tablesaw/docs/Tutorial.txt)
+```
+
+### Cross Tabs
+
+Tablesaw lets you easily produce two-dimensional cross-tabulations (“cross tabs”) of counts and proportions with row
+and column subtotals. Here’s a count example where we look at the interaction of tornado severity and US state:
+
+```java
+@@snip [crosstabs](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+
+```
+
+```java
+@@snip [crosstabs](./output/tech/tablesaw/docs/Tutorial.txt)
+```
+
+### Putting it all together
+
+Now that you've seen the pieces, we can put them together to perform a more complex data analysis. Lets say we want
+to know how frequently Tornadoes occur in the summer. Here''s one way to approach that:
+
+Let's start by getting only those tornadoes that occurred in the summer. 
+
+```java
+@@snip [all_together_where](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+```
+
+To get the frequency, we calculate the difference in days between successive tornadoes. The *lag()* method creates a
+column where every value equals the previous value (the prior row) of the source column. Then we can simply get the
+difference in days between the two dates. DateColumn has a method *daysUntil()* that does this. 
+It returns a NumberColumn that we'll call "delta". 
+
+```java
+@@snip [all_together_lag](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+```
+
+Now we simply calculate the mean of the delta column. Splitting on year keeps us from inadvertently including the time
+between the last tornado of one summer and the first tornado of the next.
+
+```java
+@@snip [all_together_summarize](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+```
+
+Printing summary gives us the answer by year. 
+
+```java
+@@snip [all_together_summarize](./output/tech/tablesaw/docs/Tutorial.txt)
+...
+```
+
+To get a DOUBLE for the entire period, we can take the average of the annual means. 
+
+```java
+@@snip [all_together_single_col_summary](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+
+// Average days between tornadoes in the summer:
+@@snip [all_together_single_col_summary](./output/tech/tablesaw/docs/Tutorial.txt)
+
+```
+
+### Saving your data
+
+To save a table, you can write it as a CSV file:
+
+```java
+@@snip [write_csv](./src/main/java/tech/tablesaw/docs/Tutorial.java)
+```
+
+And that’s it for the introduction. Please see the User Guide for more information.
\ No newline at end of file
diff --git a/docs/userguide/AddingColumns.md b/docs/main/userguide/AddingColumns.md
similarity index 100%
rename from docs/userguide/AddingColumns.md
rename to docs/main/userguide/AddingColumns.md
diff --git a/docs/userguide/BarsAndPies.md b/docs/main/userguide/BarsAndPies.md
similarity index 100%
rename from docs/userguide/BarsAndPies.md
rename to docs/main/userguide/BarsAndPies.md
diff --git a/docs/userguide/Histograms.md b/docs/main/userguide/Histograms.md
similarity index 100%
rename from docs/userguide/Histograms.md
rename to docs/main/userguide/Histograms.md
diff --git a/docs/userguide/Introduction_to_Plotting.md b/docs/main/userguide/Introduction_to_Plotting.md
similarity index 100%
rename from docs/userguide/Introduction_to_Plotting.md
rename to docs/main/userguide/Introduction_to_Plotting.md
diff --git a/docs/userguide/ScatterPlots.md b/docs/main/userguide/ScatterPlots.md
similarity index 100%
rename from docs/userguide/ScatterPlots.md
rename to docs/main/userguide/ScatterPlots.md
diff --git a/docs/userguide/Table processing without loops.md b/docs/main/userguide/Table processing without loops.md
similarity index 100%
rename from docs/userguide/Table processing without loops.md
rename to docs/main/userguide/Table processing without loops.md
diff --git a/docs/userguide/TimeSeries.md b/docs/main/userguide/TimeSeries.md
similarity index 100%
rename from docs/userguide/TimeSeries.md
rename to docs/main/userguide/TimeSeries.md
diff --git a/docs/userguide/Visualization_custom.md b/docs/main/userguide/Visualization_custom.md
similarity index 100%
rename from docs/userguide/Visualization_custom.md
rename to docs/main/userguide/Visualization_custom.md
diff --git a/docs/userguide/columns.md b/docs/main/userguide/columns.md
similarity index 100%
rename from docs/userguide/columns.md
rename to docs/main/userguide/columns.md
diff --git a/docs/userguide/crosstabs.md b/docs/main/userguide/crosstabs.md
similarity index 100%
rename from docs/userguide/crosstabs.md
rename to docs/main/userguide/crosstabs.md
diff --git a/docs/userguide/filters.md b/docs/main/userguide/filters.md
similarity index 100%
rename from docs/userguide/filters.md
rename to docs/main/userguide/filters.md
diff --git a/docs/userguide/images/eda/box1.png b/docs/main/userguide/images/eda/box1.png
similarity index 100%
rename from docs/userguide/images/eda/box1.png
rename to docs/main/userguide/images/eda/box1.png
diff --git a/docs/userguide/images/eda/bush_heatmap1.png b/docs/main/userguide/images/eda/bush_heatmap1.png
similarity index 100%
rename from docs/userguide/images/eda/bush_heatmap1.png
rename to docs/main/userguide/images/eda/bush_heatmap1.png
diff --git a/docs/userguide/images/eda/bush_time_series.png b/docs/main/userguide/images/eda/bush_time_series.png
similarity index 100%
rename from docs/userguide/images/eda/bush_time_series.png
rename to docs/main/userguide/images/eda/bush_time_series.png
diff --git a/docs/userguide/images/eda/bush_time_series2.png b/docs/main/userguide/images/eda/bush_time_series2.png
similarity index 100%
rename from docs/userguide/images/eda/bush_time_series2.png
rename to docs/main/userguide/images/eda/bush_time_series2.png
diff --git a/docs/userguide/images/eda/candlestick1.png b/docs/main/userguide/images/eda/candlestick1.png
similarity index 100%
rename from docs/userguide/images/eda/candlestick1.png
rename to docs/main/userguide/images/eda/candlestick1.png
diff --git a/docs/userguide/images/eda/fatalities_by_scale.png b/docs/main/userguide/images/eda/fatalities_by_scale.png
similarity index 100%
rename from docs/userguide/images/eda/fatalities_by_scale.png
rename to docs/main/userguide/images/eda/fatalities_by_scale.png
diff --git a/docs/userguide/images/eda/hist_overlay.png b/docs/main/userguide/images/eda/hist_overlay.png
similarity index 100%
rename from docs/userguide/images/eda/hist_overlay.png
rename to docs/main/userguide/images/eda/hist_overlay.png
diff --git a/docs/userguide/images/eda/histogram.png b/docs/main/userguide/images/eda/histogram.png
similarity index 100%
rename from docs/userguide/images/eda/histogram.png
rename to docs/main/userguide/images/eda/histogram.png
diff --git a/docs/userguide/images/eda/histogram1.png b/docs/main/userguide/images/eda/histogram1.png
similarity index 100%
rename from docs/userguide/images/eda/histogram1.png
rename to docs/main/userguide/images/eda/histogram1.png
diff --git a/docs/userguide/images/eda/histogram2.png b/docs/main/userguide/images/eda/histogram2.png
similarity index 100%
rename from docs/userguide/images/eda/histogram2.png
rename to docs/main/userguide/images/eda/histogram2.png
diff --git a/docs/userguide/images/eda/histogram2d.png b/docs/main/userguide/images/eda/histogram2d.png
similarity index 100%
rename from docs/userguide/images/eda/histogram2d.png
rename to docs/main/userguide/images/eda/histogram2d.png
diff --git a/docs/userguide/images/eda/ohlc1.png b/docs/main/userguide/images/eda/ohlc1.png
similarity index 100%
rename from docs/userguide/images/eda/ohlc1.png
rename to docs/main/userguide/images/eda/ohlc1.png
diff --git a/docs/userguide/images/eda/pie.png b/docs/main/userguide/images/eda/pie.png
similarity index 100%
rename from docs/userguide/images/eda/pie.png
rename to docs/main/userguide/images/eda/pie.png
diff --git a/docs/userguide/images/eda/robberies_area.png b/docs/main/userguide/images/eda/robberies_area.png
similarity index 100%
rename from docs/userguide/images/eda/robberies_area.png
rename to docs/main/userguide/images/eda/robberies_area.png
diff --git a/docs/userguide/images/eda/robberies_line.png b/docs/main/userguide/images/eda/robberies_line.png
similarity index 100%
rename from docs/userguide/images/eda/robberies_line.png
rename to docs/main/userguide/images/eda/robberies_line.png
diff --git a/docs/userguide/images/eda/scatter_2_Yaxes.png b/docs/main/userguide/images/eda/scatter_2_Yaxes.png
similarity index 100%
rename from docs/userguide/images/eda/scatter_2_Yaxes.png
rename to docs/main/userguide/images/eda/scatter_2_Yaxes.png
diff --git a/docs/userguide/images/eda/tornado_bar_groups.png b/docs/main/userguide/images/eda/tornado_bar_groups.png
similarity index 100%
rename from docs/userguide/images/eda/tornado_bar_groups.png
rename to docs/main/userguide/images/eda/tornado_bar_groups.png
diff --git a/docs/userguide/images/eda/tornado_box.png b/docs/main/userguide/images/eda/tornado_box.png
similarity index 100%
rename from docs/userguide/images/eda/tornado_box.png
rename to docs/main/userguide/images/eda/tornado_box.png
diff --git a/docs/userguide/images/eda/tornado_pareto.png b/docs/main/userguide/images/eda/tornado_pareto.png
similarity index 100%
rename from docs/userguide/images/eda/tornado_pareto.png
rename to docs/main/userguide/images/eda/tornado_pareto.png
diff --git a/docs/userguide/images/eda/wine_bubble.png b/docs/main/userguide/images/eda/wine_bubble.png
similarity index 100%
rename from docs/userguide/images/eda/wine_bubble.png
rename to docs/main/userguide/images/eda/wine_bubble.png
diff --git a/docs/userguide/images/eda/wine_bubble_3d.png b/docs/main/userguide/images/eda/wine_bubble_3d.png
similarity index 100%
rename from docs/userguide/images/eda/wine_bubble_3d.png
rename to docs/main/userguide/images/eda/wine_bubble_3d.png
diff --git a/docs/userguide/images/eda/wine_bubble_with_groups.png b/docs/main/userguide/images/eda/wine_bubble_with_groups.png
similarity index 100%
rename from docs/userguide/images/eda/wine_bubble_with_groups.png
rename to docs/main/userguide/images/eda/wine_bubble_with_groups.png
diff --git a/docs/userguide/images/eda/wine_category_3dScatter.png b/docs/main/userguide/images/eda/wine_category_3dScatter.png
similarity index 100%
rename from docs/userguide/images/eda/wine_category_3dScatter.png
rename to docs/main/userguide/images/eda/wine_category_3dScatter.png
diff --git a/docs/userguide/images/eda/wine_category_scatter.png b/docs/main/userguide/images/eda/wine_category_scatter.png
similarity index 100%
rename from docs/userguide/images/eda/wine_category_scatter.png
rename to docs/main/userguide/images/eda/wine_category_scatter.png
diff --git a/docs/userguide/images/eda/wine_scatter.png b/docs/main/userguide/images/eda/wine_scatter.png
similarity index 100%
rename from docs/userguide/images/eda/wine_scatter.png
rename to docs/main/userguide/images/eda/wine_scatter.png
diff --git a/docs/userguide/images/eda/wine_simple_3dScatter.png b/docs/main/userguide/images/eda/wine_simple_3dScatter.png
similarity index 100%
rename from docs/userguide/images/eda/wine_simple_3dScatter.png
rename to docs/main/userguide/images/eda/wine_simple_3dScatter.png
diff --git a/docs/userguide/images/eda/wine_simple_bubble.png b/docs/main/userguide/images/eda/wine_simple_bubble.png
similarity index 100%
rename from docs/userguide/images/eda/wine_simple_bubble.png
rename to docs/main/userguide/images/eda/wine_simple_bubble.png
diff --git a/docs/userguide/images/eda/wine_simple_scatter.png b/docs/main/userguide/images/eda/wine_simple_scatter.png
similarity index 100%
rename from docs/userguide/images/eda/wine_simple_scatter.png
rename to docs/main/userguide/images/eda/wine_simple_scatter.png
diff --git a/docs/userguide/images/ml/regression/histogram.png b/docs/main/userguide/images/ml/regression/histogram.png
similarity index 100%
rename from docs/userguide/images/ml/regression/histogram.png
rename to docs/main/userguide/images/ml/regression/histogram.png
diff --git a/docs/userguide/images/ml/regression/moneyball-3_1.png b/docs/main/userguide/images/ml/regression/moneyball-3_1.png
similarity index 100%
rename from docs/userguide/images/ml/regression/moneyball-3_1.png
rename to docs/main/userguide/images/ml/regression/moneyball-3_1.png
diff --git a/docs/userguide/images/ml/regression/run diff vs wins.png b/docs/main/userguide/images/ml/regression/run diff vs wins.png
similarity index 100%
rename from docs/userguide/images/ml/regression/run diff vs wins.png
rename to docs/main/userguide/images/ml/regression/run diff vs wins.png
diff --git a/docs/userguide/images/ml/regression/runs scored model.png b/docs/main/userguide/images/ml/regression/runs scored model.png
similarity index 100%
rename from docs/userguide/images/ml/regression/runs scored model.png
rename to docs/main/userguide/images/ml/regression/runs scored model.png
diff --git a/docs/userguide/images/ml/regression/wins by year.png b/docs/main/userguide/images/ml/regression/wins by year.png
similarity index 100%
rename from docs/userguide/images/ml/regression/wins by year.png
rename to docs/main/userguide/images/ml/regression/wins by year.png
diff --git a/docs/userguide/images/mrd/clearance_line.png b/docs/main/userguide/images/mrd/clearance_line.png
similarity index 100%
rename from docs/userguide/images/mrd/clearance_line.png
rename to docs/main/userguide/images/mrd/clearance_line.png
diff --git a/docs/userguide/images/mrd/cum_unsolved_mrd1.png b/docs/main/userguide/images/mrd/cum_unsolved_mrd1.png
similarity index 100%
rename from docs/userguide/images/mrd/cum_unsolved_mrd1.png
rename to docs/main/userguide/images/mrd/cum_unsolved_mrd1.png
diff --git a/docs/userguide/images/mrd/ri_murders_pie.png b/docs/main/userguide/images/mrd/ri_murders_pie.png
similarity index 100%
rename from docs/userguide/images/mrd/ri_murders_pie.png
rename to docs/main/userguide/images/mrd/ri_murders_pie.png
diff --git a/docs/userguide/images/mrd/total_mrd_line.png b/docs/main/userguide/images/mrd/total_mrd_line.png
similarity index 100%
rename from docs/userguide/images/mrd/total_mrd_line.png
rename to docs/main/userguide/images/mrd/total_mrd_line.png
diff --git a/docs/userguide/images/tornado.scatter.png b/docs/main/userguide/images/tornado.scatter.png
similarity index 100%
rename from docs/userguide/images/tornado.scatter.png
rename to docs/main/userguide/images/tornado.scatter.png
diff --git a/docs/userguide/importing_data.md b/docs/main/userguide/importing_data.md
similarity index 100%
rename from docs/userguide/importing_data.md
rename to docs/main/userguide/importing_data.md
diff --git a/docs/userguide/introduction.md b/docs/main/userguide/introduction.md
similarity index 100%
rename from docs/userguide/introduction.md
rename to docs/main/userguide/introduction.md
diff --git a/docs/userguide/mapping.md b/docs/main/userguide/mapping.md
similarity index 100%
rename from docs/userguide/mapping.md
rename to docs/main/userguide/mapping.md
diff --git a/docs/userguide/ml/Moneyball Linear regression.md b/docs/main/userguide/ml/Moneyball Linear regression.md
similarity index 100%
rename from docs/userguide/ml/Moneyball Linear regression.md
rename to docs/main/userguide/ml/Moneyball Linear regression.md
diff --git a/docs/userguide/reducing.md b/docs/main/userguide/reducing.md
similarity index 100%
rename from docs/userguide/reducing.md
rename to docs/main/userguide/reducing.md
diff --git a/docs/userguide/rows.md b/docs/main/userguide/rows.md
similarity index 100%
rename from docs/userguide/rows.md
rename to docs/main/userguide/rows.md
diff --git a/docs/userguide/sorting.md b/docs/main/userguide/sorting.md
similarity index 100%
rename from docs/userguide/sorting.md
rename to docs/main/userguide/sorting.md
diff --git a/docs/userguide/tables.md b/docs/main/userguide/tables.md
similarity index 100%
rename from docs/userguide/tables.md
rename to docs/main/userguide/tables.md
diff --git a/docs/userguide/toc.md b/docs/main/userguide/toc.md
similarity index 100%
rename from docs/userguide/toc.md
rename to docs/main/userguide/toc.md
diff --git a/docs/pom.xml b/docs/pom.xml
new file mode 100644
index 00000000..6fe9f44c
--- /dev/null
+++ b/docs/pom.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>tech.tablesaw</groupId>
+        <artifactId>tablesaw-parent</artifactId>
+        <version>0.34.3-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>tablesaw-docs</artifactId>
+
+    <pluginRepositories>
+        <pluginRepository>
+            <id>jitpack.io</id>
+            <url>https://jitpack.io</url>
+        </pluginRepository>
+    </pluginRepositories>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>com.coveo</groupId>
+                <artifactId>fmt-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <version>3.1.0</version>
+                <configuration>
+                    <shadedArtifactAttached>true</shadedArtifactAttached>
+                    <shadedClassifierName>shaded</shadedClassifierName>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>com.github.ryancerf</groupId>
+                <artifactId>choss-maven-plugin</artifactId>
+                <version>v0.02</version>
+                <configuration>
+                    <docsSourceDirectory>./main/</docsSourceDirectory>
+                    <docsTargetDirectory>./dist/</docsTargetDirectory>
+                </configuration>
+                <!--Add configuraton to set docsSourceDirectory-->
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>build-docs</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <version>1.2.1</version>
+                <configuration>
+                    <mainClass>tech.tablesaw.docs.Main</mainClass>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>tech.tablesaw</groupId>
+            <artifactId>tablesaw-core</artifactId>
+            <version>0.34.3-SNAPSHOT</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+</project>
+
diff --git a/docs/src/main/java/tech/tablesaw/docs/DocsSourceFile.java b/docs/src/main/java/tech/tablesaw/docs/DocsSourceFile.java
new file mode 100644
index 00000000..4918c5a2
--- /dev/null
+++ b/docs/src/main/java/tech/tablesaw/docs/DocsSourceFile.java
@@ -0,0 +1,7 @@
+package tech.tablesaw.docs;
+
+import java.io.IOException;
+
+interface DocsSourceFile {
+  void run() throws IOException;
+}
diff --git a/docs/src/main/java/tech/tablesaw/docs/Main.java b/docs/src/main/java/tech/tablesaw/docs/Main.java
new file mode 100644
index 00000000..a09a5770
--- /dev/null
+++ b/docs/src/main/java/tech/tablesaw/docs/Main.java
@@ -0,0 +1,20 @@
+package tech.tablesaw.docs;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+/** Main class that will run all the docs. All Docs classes have to be registered in main. */
+public class Main {
+
+  public static void main(String[] args) throws IOException {
+    List<DocsSourceFile> docsClasses =
+        Arrays.asList(
+            // Register new docs classes here.
+            new Tutorial());
+
+    for (DocsSourceFile docsClass : docsClasses) {
+      docsClass.run();
+    }
+  }
+}
diff --git a/docs/src/main/java/tech/tablesaw/docs/OutputWriter.java b/docs/src/main/java/tech/tablesaw/docs/OutputWriter.java
new file mode 100644
index 00000000..c212d9de
--- /dev/null
+++ b/docs/src/main/java/tech/tablesaw/docs/OutputWriter.java
@@ -0,0 +1,65 @@
+package tech.tablesaw.docs;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.nio.file.StandardOpenOption.APPEND;
+
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Saves string snippets to an output file so they can be used in the docs.
+ *
+ * <p TODO clean this up. It is a bit of a hack.
+ */
+public class OutputWriter {
+  private final Class<?> clazz;
+
+  public OutputWriter(Class<?> clazz) {
+    this.clazz = clazz;
+    try {
+      emptyFile();
+    } catch (IOException e) {
+      throw new RuntimeException(e.getMessage(), e);
+    }
+  }
+
+  /**
+   * Write the output of arbitrary java code to a file so it can be used in the documentation.
+   *
+   * @param object the object to write to the text file. Will call toString();
+   * @param tag the tag to mark the snippet with.
+   * @throws IOException
+   */
+  public void write(Object object, String tag) throws IOException {
+    List<String> lines = new ArrayList<>();
+    lines.add("// @@ " + tag);
+    lines.addAll(Arrays.asList(object.toString().split(System.lineSeparator())));
+    lines.add("// @@ " + tag);
+    lines.add(System.lineSeparator());
+    Files.write(getPath(), lines, UTF_8, APPEND);
+  }
+
+  private Path getPath() {
+    URL fullPath = clazz.getResource(clazz.getSimpleName() + ".class");
+    String path = fullPath.toString().split("classes")[1];
+    path = path.replace(".class", ".txt");
+    path = "./output" + path;
+    return Paths.get(path);
+  }
+
+  private void emptyFile() throws IOException {
+    if (Files.exists(getPath())) {
+      Files.delete(getPath());
+    }
+    if (!Files.exists(getPath().getParent())) {
+      Files.createDirectories(getPath().getParent());
+    }
+    Files.createFile(getPath());
+  }
+}
diff --git a/docs/src/main/java/tech/tablesaw/docs/Tutorial.java b/docs/src/main/java/tech/tablesaw/docs/Tutorial.java
new file mode 100644
index 00000000..59a961c6
--- /dev/null
+++ b/docs/src/main/java/tech/tablesaw/docs/Tutorial.java
@@ -0,0 +1,168 @@
+package tech.tablesaw.docs;
+
+import static tech.tablesaw.aggregate.AggregateFunctions.count;
+import static tech.tablesaw.aggregate.AggregateFunctions.mean;
+import static tech.tablesaw.aggregate.AggregateFunctions.median;
+
+import java.io.IOException;
+import tech.tablesaw.aggregate.CrossTab;
+import tech.tablesaw.api.DateColumn;
+import tech.tablesaw.api.IntColumn;
+import tech.tablesaw.api.QuerySupport;
+import tech.tablesaw.api.StringColumn;
+import tech.tablesaw.api.Table;
+
+public class Tutorial implements DocsSourceFile {
+
+  public static OutputWriter outputWriter = new OutputWriter(Tutorial.class);
+
+  public static void main(String[] args) throws IOException {
+    Tutorial tutorial = new Tutorial();
+    tutorial.run();
+  }
+
+  public void run() throws IOException {
+    // @@ table_read
+    Table tornadoes = Table.read().csv("../data/tornadoes_1950-2014.csv");
+    // @@ table_read
+
+    outputWriter.write(
+        // @@ table_columns
+        tornadoes.columnNames()
+        // @@ table_columns
+        ,
+        "table_columns");
+
+    outputWriter.write(
+        // @@ table_shape
+        tornadoes.shape()
+        // @@ table_shape
+        ,
+        "table_shape");
+
+    outputWriter.write(
+        // @@ table_structure
+        tornadoes.structure().printAll()
+        // @@ table_structure
+        ,
+        "table_structure");
+
+    // @@ print_table
+    System.out.println(tornadoes);
+    // @@ print_table
+    outputWriter.write(tornadoes, "print_table");
+
+    outputWriter.write(
+        // @@ filter_structure
+        tornadoes
+            .structure()
+            .where(tornadoes.structure().stringColumn("Column Type").isEqualTo("DOUBLE"))
+        // @@ filter_structure
+        ,
+        "filter_structure");
+
+    outputWriter.write(
+        // @@ first_n
+        tornadoes.first(3)
+        // @@ first_n
+        ,
+        "first_n");
+
+    // @@ date_col
+    StringColumn month = tornadoes.dateColumn("Date").month();
+    // @@ date_col
+
+    // @@ add_date_col
+    tornadoes.addColumns(month);
+    // @@ add_date_col
+
+    // @@ remove_col
+    tornadoes.removeColumns("State No");
+    // @@ remove_col
+
+    // @@ sort_on
+    tornadoes.sortOn("-Fatalities");
+    // @@ sort_on
+
+    outputWriter.write(
+        // @@ summary
+        tornadoes.column("Fatalities").summary().print()
+        // @@ summary
+        ,
+        "summary");
+
+    // @@ filtering
+    Table result = tornadoes.where(tornadoes.intColumn("Fatalities").isGreaterThan(0));
+    result = tornadoes.where(result.dateColumn("Date").isInApril());
+    result =
+        tornadoes.where(
+            result
+                .intColumn("Width")
+                .isGreaterThan(300) // 300 yards
+                .or(result.doubleColumn("Length").isGreaterThan(10))); // 10 miles
+
+    result = result.select("State", "Date");
+
+    // @@ filtering
+    outputWriter.write(result.first(3), "filtering");
+
+    // @@ totals
+    Table injuriesByScale = tornadoes.summarize("Injuries", median).by("Scale").sortOn("Scale");
+    injuriesByScale.setName("Median injuries by Tornado Scale");
+    // @@ totals
+    outputWriter.write(injuriesByScale.first(10), "totals");
+
+    outputWriter.write(
+        // @@ crosstabs
+        CrossTab.counts(tornadoes, tornadoes.stringColumn("State"), tornadoes.intColumn("Scale"))
+            .first(10)
+        // @@ crosstabs
+        ,
+        "crosstabs");
+
+    // Putting it all togeather.
+
+    // @@ all_together_where
+    Table summer =
+        tornadoes.where(
+            QuerySupport.or(
+                // In June
+                QuerySupport.and(
+                    t -> t.dateColumn("Date").month().isEqualTo("JUNE"),
+                    t -> t.dateColumn("Date").dayOfMonth().isGreaterThanOrEqualTo(21)),
+                // In July or August
+                t -> t.dateColumn("Date").month().isIn("JULY", "AUGUST"),
+                // In September
+                QuerySupport.or(
+                    t -> t.dateColumn("Date").month().isEqualTo("SEPTEMBER"),
+                    t -> t.dateColumn("Date").dayOfMonth().isLessThan(22))));
+    // @@ all_together_where
+
+    // @@ all_together_lag
+    summer = summer.sortAscendingOn("Date", "Time");
+    summer.addColumns(summer.dateColumn("Date").lag(1));
+
+    DateColumn summerDate = summer.dateColumn("Date");
+    DateColumn laggedDate = summer.dateColumn("Date lag(1)");
+
+    IntColumn delta = laggedDate.daysUntil(summerDate);
+    summer.addColumns(delta);
+    // @@ all_together_lag
+
+    // @@ all_together_summarize
+    Table summary = summer.summarize(delta, mean, count).by(summerDate.year());
+    // @@ all_together_summarize
+    outputWriter.write(summary.first(5), "all_together_summarize");
+
+    outputWriter.write(
+        // @@ all_together_single_col_summary
+        summary.nCol(1).mean()
+        // @@ all_together_single_col_summary
+        ,
+        "all_together_single_col_summary");
+
+    // @@ write_csv
+    tornadoes.write().csv("rev_tornadoes_1950-2014.csv");
+    // @@ write_csv
+  }
+}
diff --git a/docs/tutorial.md b/docs/tutorial.md
deleted file mode 100644
index 9f481efd..00000000
--- a/docs/tutorial.md
+++ /dev/null
@@ -1,267 +0,0 @@
-
-
-# Tablesaw: A brief tutorial
-
-Tablesaw is a large library. We'll use Tablesaw to look at data about Tornadoes. If you haven't already done so, we strongly recommend that you read the Getting Started guide, before continuing here. 
-
-## Exploring Tornadoes 
-
-To give a better sense of how Tablesaw works, we’ll use a tornado data set from NOAA. Here’s what we’ll cover:
-
-* Reading and writing CSV files
-* Viewing table metadata
-* Adding and removing columns
-* Printing the first few rows for a peak at the data
-* Sorting
-* Running descriptive stats (mean, min, max, etc.)
-* Performing mapping operations over columns
-* Filtering rows
-* Computing cross-tabs
-
-All the data is in the Tablesaw *data* folder. The code is taken from the TornadoExample test class.
-
-### Read a CSV file
-
-Here we read a csv file of tornado data. Tablesaw infers the column types by sampling the data.
-
-```java
-Table tornadoes = Table.read().csv("../data/tornadoes_1950-2014.csv");
-```
-
-**Note:** that the file is addressed relative to the current working directory. You may have to change it for your code. 
-
-### Viewing table metadata
-
-Often, the best way to start is to print the column names for reference:
-
-```java
-tornadoes.columnNames();
-
->>	Date, Time, State, State No, Scale, Injuries, Fatalities, Start Lat, Start Lon, 	Length, Width]
-```
-
-The *shape()* method displays the row and column counts:
-
-    tornadoes.shape();
-    >>	59945 rows X 10 cols
-
-*structure()* shows the index, name and type of each column
-
-```java
-tornadoes.structure().printAll();
-
->>  Structure of data/tornadoes_1950-2014.csv
-        Index Column Names Column Type 
-        0     Date         LOCAL_DATE  
-        1     Time         LOCAL_TIME  
-        2     State        STRING    
-        3     State No     DOUBLE     
-        4     Scale        DOUBLE     
-        5     Injuries     INTEGER     
-        6     Fatalities   INTEGER     
-        7     Start Lat    DOUBLE       
-        8     Start Lon    DOUBLE       
-        9     Length       DOUBLE       
-        10    Width        DOUBLE       
-```
-
-Like many Tablesaw methods, *structure()* returns a table.  You can then produce a string representation for display. For convenience, calling *toString()* on a table invokes *print()*, which produces a string representation of the table table. To display the table then, you can simply call. 
-
-`System.out.println(table);`
-
-You can also perform other table operations on it. For example, the code below removes all columns whose type isn’t DOUBLE:
-
-    tornadoes.structure().selectWhere(column("Column Type").isEqualTo("DOUBLE"));
-    
-    >>  Structure of data/tornadoes_1950-2014.csv
-            Index Column Name Column Type 
-            3     State No    DOUBLE     
-            4     Scale       DOUBLE     
-            5     Injuries    DOUBLE     
-            6     Fatalities  DOUBLE     
-
-Of course, that also returned a table. We’ll cover selecting rows in more detail later.
-
-### Previewing data
-
-The *first(n)* method returns a new table containing the first n rows.
-
-    table.first(3);
-    
-    >>  Date       Time     State Scale Injuries Fatalities Start Lat Start Lon Length Width 
-        1950-01-03 11:00:00 MO    3     3        0          38.77     -90.22    9.5    150.0 
-        1950-01-03 11:00:00 MO    3     3        0          38.77     -90.22    6.2    150.0 
-        1950-01-03 11:10:00 IL    3     0        0          38.82     -90.12    3.3    100.0 
-
-### Mapping operations
-
-Mapping operations in Tablesaw take one or more columns as inputs and produce a new column as output. We can map arbitrary expressions onto the table, but many common operations are built in. You can, for example, calculate the difference in days, weeks, or years between the values in two date columns. The method below extracts the Month name from the date column into a new column.
-
-```java
-StringColumn month = tornadoes.dateColumn("Date").month();
-```
-
-Now that you have a new column, you can add it to the table:
-
-```java
-tornadoes.addColumn(month);
-```
-
-You can remove columns from tables to save memory or reduce clutter:
-
-```java
-tornadoes.removeColumn("State No");
-```
-
-### Sorting
-
-Now lets sort the table in reverse order by the id column. The negative sign before the name indicates a descending sort.
-
-```java
-tornadoes.sortOn("-Fatalities");
-```
-### Descriptive statistics
-
-Descriptive statistics are calculated using the summary() method:
-
-```java
-table.column("Fatalities").summary().print();
-
->>  Measure  Value     
-    n        1590.0    
-    Missing  0.0       
-    Mean     4.2779875 
-    Min      1.0       
-    Max      158.0     
-    Range    157.0     
-    Std. Dev 9.573451
-```
-
-### Filtering
-
-You can write your own methods to filter rows, but it’s easier to use the built-in filter classes as shown below:
-
-```java 
-result = tornadoes.selectWhere(doubleColumn("Fatalities").isGreaterThan(0));
-
-result = tornadoes.selectWhere(dateColumn("Date").isInApril());
-
-result = tornadoes.selectWhere(either
-           (doubleColumn("Width").isGreaterThan(300)),   // 300 yards
-           (doubleColumn("Length").isGreaterThan(10)));  // 10 miles
-
-result = tornadoes.select("State", "Date").where(column("Date").isInQ2());
-```
-
-The last example above returns a table containing only the columns named in *select()* parameters, rather than all the columns in the original.
-
-### Totals and sub-totals
-
-Column metrics can be calculated using methods like *sum()*, *product()*, *mean()*, *max()*, etc.
-
-You can apply those methods to a table, calculating results on one column, grouped by the values in another.
-
-```java
-Table injuriesByScale = tornadoes.summarize("Injuries", median).by("Scale");
-injuriesByScale.setName("Median injuries by Tornado Scale");
-```
-This produces the following table, in which Group represents the Tornado Scale and Median the median injures for that group:
-
-    Median injuries by Tornado Scale
-    >>  Group Median 
-        -9    0.0    
-        0     0.0    
-        1     0.0    
-        2     0.0    
-        3     1.0    
-        4     12.0   
-        5     107.0  
-
-### Cross Tabs
-
-Tablesaw lets you easily produce two-dimensional cross-tabulations (“cross tabs”) of counts and proportions with row and column subtotals. Here’s a count example where we look at the interaction of tornado severity and US state:
-```java
-CrossTab.counts(t, t.stringColumn("State"), t.shortColumn("Scale"));
-```
-
-```java
->>  Crosstab Counts: State x Scale
-          -9 0     1     2    3    4   5  total 
-    AL    0  623   769   424  141  37  11 2005  
-    AR    0  485   666   419  161  28  0  1759  
-    AZ    0  145   70    15   2    0   0  232   
-    ... snipped 
-    WI    0  447   517   267  55   18  2  1306  
-    WV    0  37    67    22   7    0   0  133   
-    WY    0  405   178   51   11   0   0  645   
-    Total 44 27253 20009 9067 2580 670 68 59691`
-```
-
-### Putting it all together
-
-Now that you've seen the pieces, we can put them together to perform a more complex data analysis. Lets say we want to know how frequently Tornadoes occur in the summer. Here''s one way to approach that:
-
-Let's start by getting only those tornadoes that occured in the summer. 
-
-```java
-DateColumn date = tornadoes.dateColumn("Date");
-
-Filter summerFilter =
-                anyOf( 	// from June 21st, through September 22nd       
-                        both(date.month().isEqualTo("JUNE"), 
-                            date.dayOfMonth().isGreaterThanOrEqualTo(21)),
-    					date.month().isIn("JULY", "AUGUST"),
-                        both(date.month().isEqualTo("SEPTEMBER"),
-                            date.dayOfMonth().isLessThan(22)));
-
-Table summer = tornadoes.selectWhere(summerFilter);
-```
-
-To get the frequency, we calculate the difference in days between successive tornadoes. The *lag()* method creates a column where every value equals the previous value (the prior row) of the source column. Then we can simply get the difference in days between the two dates. DateColumn has a method *daysUntil()* that does this.  It returns a NumberColumn that we'll call "delta". 
-
-```java
-summer = summer.sortAscendingOn("Date", "Time");
-summer.addColumn(summer.dateColumn("Date").lag(1));
-
-DateColumn summerDate = summer.dateColumn("Date");
-DateColumn laggedDate = summer.dateColumn("Date lag(1)");
-
-DoubleColumn delta = laggedDate.daysUntil(summerDate);
-summer.addColumn(delta);
-```
-
-Now we simply caculate the mean of the delta column. Splitting on year keeps us from inadvertently including the time between the last tornado of one summer and the first tornado of the next.
-
-```java
-Table summary = summer.summarize(delta, mean, count).by(summerDate.year());
-```
-
-Printing summary gives us the answer by year. 
-
-```
-     Date year  |  Mean [Date lag(1) - Date]  |  Count [Date lag(1) - Date]  |
-    --------------------------------------------------------------------------
-        1950.0  |         1.9782608695652173  |                        47.0  |
-        1951.0  |          4.684210526315789  |                        76.0  |
-        1952.0  |          5.707692307692312  |                        65.0  |
-        1953.0  |          4.805194805194803  |                        77.0  |
-...
-```
-
-To get a DOUBLE for the entire period, we can take the average of the annual means. 
-
-```
-summary.nCol(1).mean();
->>	Average days between tornadoes in the summer: 1.761269943549373
-```
-
-### Saving your data
-
-To save a table, you can write it as a CSV file:
-
-```java
-tornadoes.write().csv("data/rev_tornadoes_1950-2014.csv");
-```
-
-And that’s it for the introduction. Please see the User Guide for more information.
-
diff --git a/pom.xml b/pom.xml
index cfbf7e5a..f451568f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,6 +50,7 @@
         <module>html</module>
         <module>json</module>
         <module>jsplot</module>
+        <module>docs</module>
     </modules>
 
     <profiles>


Test patch:
diff --git a/core/src/test/java/tech/tablesaw/api/FloatColumnTest.java b/core/src/test/java/tech/tablesaw/api/FloatColumnTest.java
index 2e49443c..e2926a23 100644
--- a/core/src/test/java/tech/tablesaw/api/FloatColumnTest.java
+++ b/core/src/test/java/tech/tablesaw/api/FloatColumnTest.java
@@ -15,24 +15,34 @@
 package tech.tablesaw.api;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import org.junit.jupiter.api.Test;
 
 public class FloatColumnTest {
 
   @Test
-  public void testAppendFloat() {
-    final FloatColumn floatColumn = FloatColumn.create("floats");
-    final Float floatValue = 2.5f;
+  public void appendFloat() {
+    FloatColumn floatColumn = FloatColumn.create("floats");
+    Float floatValue = 2.5f;
     floatColumn.append(floatValue);
     assertEquals(floatValue, floatColumn.get(0));
   }
 
   @Test
-  public void testAppendFloatObject() {
-    final FloatColumn floatColumn = FloatColumn.create("floats");
-    final Float floatObject = 2.5f;
+  public void appendFloatObject() {
+    FloatColumn floatColumn = FloatColumn.create("floats");
+    Float floatObject = 2.5f;
     floatColumn.append(floatObject);
     assertEquals(floatObject, floatColumn.get(0));
   }
+
+  @Test
+  public void createFromObjectArray() {
+    Float[] floats = new Float[] {2.5f, null, 4.0f};
+    FloatColumn floatColumn = FloatColumn.create("floats", floats);
+    assertEquals(2.5f, floatColumn.get(0));
+    assertTrue(floatColumn.isMissing(1));
+    assertEquals(4.0f, floatColumn.get(2));
+  }
 }