defmodule LiterateCompiler.TOC do
Purpose
This generates a table of contents in yaml for Jekyll
	@empty_accumulator []
	alias LiterateCompiler.Extensions
	alias LiterateCompiler.Outputter
Public API
	def make_toc(files, args) do
		split = split(files, @empty_accumulator)
		sorted = Enum.sort(split, &sorter/2)
		toc = build_tree(sorted, args, @empty_accumulator)
		# the toc starts with a line 'toc:' and a title and subfolder
		header = ["    subfolderitems:",
				  "  - title: Contents",
				  "toc:"]
		# we start indenting at 2 because the header has an indent in it
		file = indent(toc, header)
		fileandpath = Path.join([args.outputdir, "_data/contents.yml"])
		write_dir = Path.dirname(fileandpath)
		:ok = File.mkdir_p(write_dir)
		File.write(fileandpath, Enum.join(file, "\n"))
	end
Private Fns
yaml is a pain in the arse, white space matters language so you have to write an indenter
	defp indent([], acc), do: Enum.reverse(acc)
	defp indent([{ {:url, _n}, line} | t], acc) do
		newacc = pad(line, 4)
		indent(t, [newacc | acc])
	end
	defp indent([{:title, line} | t], acc) do
		newacc = pad(line, 1)
		indent(t, [newacc | acc])
	end
	defp indent([{:sub, line} | t], acc) do
		newacc = pad(line, 2)
		indent(t, [newacc | acc])
	end
	defp indent([{:page, line} | t], acc) do
		newacc = pad(line, 3)
		indent(t, [newacc | acc])
	end
	defp build_tree([], _args, acc) do
		Enum.reverse(acc)
	end
	defp build_tree([{path, file} | t], args, acc) do
		fullpath = Path.join(path ++ [file])
		IO.puts(fullpath)
		ext = Path.extname(file)
		langmodule = Extensions.get_lang_module(ext)
		# dependencies and builds bring in different file types, we don't want them in
		# the contents page
		case langmodule do
	  		:none -> build_tree(t, args, acc)
		  	_     -> case Enum.member?(args.excludes, fullpath) do
						true ->
							build_tree(t, args, acc)
						false ->
							{page, url} = get_components(path ++ [file], args)
							len = length(path)
							newacc = [{ {:url, len}, url}, {:page, page}]
							build_tree(t, args, newacc ++ acc)
			end
		end
	end
	defp get_components(path, args) do
		oldext = Path.extname(path)
		oldfile = Path.join(path)
		newfile = Outputter.make_write_file(oldfile, args.inputdir, args.outputdir, "html")
		newpath = String.split(newfile, "/")
		# do some setup
		rev = Enum.reverse(newpath)
		[file | rest] = rev
		fileroot = Path.rootname(file)
		# make the URL
		relpath = Enum.reverse(rest)
		trimmedrelpath = case relpath do
			[_, _ | t] -> t
			[_    | t] -> t
		end
		root = Path.rootname(file)
		file = Enum.join([root, ".", "html"])
		url  = Path.join(["."] ++ trimmedrelpath ++ [file])
		# make the lines for the toc
		urlline = Enum.join(["url:  ", url])
		page = case trimmedrelpath do
			[] -> Enum.join(["- page: ", fileroot, oldext])
		    _  -> pagepath = Path.join(trimmedrelpath)
				Enum.join(["- page: ", pagepath, " - ", fileroot, oldext])
		end
		# return them
		{page, urlline}
	end
	defp pad(line, n) do
		pad =  String.duplicate(" ", n * 2)
		Enum.join([pad, line])
	end
	defp split([], acc), do: acc
	defp split([h | t], acc) do
		[file | rev] = Enum.reverse(h)
		newacc = [{Enum.reverse(rev), file} | acc]
		split(t, newacc)
	end
The sorter is the hardest bit of code in the whole programme :-)
	defp sorter({path1, file1}, {path2, file2}) do
		len1 = length(path1)
		len2 = length(path2)
		len1plus = len1 + 1
		len2plus = len2 + 1
		cond do
same path, sort by filename
			path1 == path2 ->
				file1 <= file2
paths the same length, sort by path
			len1  == len2 ->
				path1 <= path2
path exactly one longer than the other
check if the 
			len1plus == len2 ->
				fname = Path.rootname(file1)
				case path1 ++ fname do
					^path2 -> true
					_      -> path1 <= path2
				end
			len1 == len2plus ->
				fname = Path.rootname(file2)
				case path2 ++ [fname] do
					^path1 -> false
					_      -> path1 <= path2
				end
otherwise see if the 
			len1  <  len2 ->
				fname = Path.rootname(file1)
				case prefix(path1 ++ [fname], path2) do
					true  -> true
					false -> path1 ++ [fname] <= path2
				end
			len1  >  len2 ->
				fname = Path.rootname(file2)
				case prefix(path2 ++ [fname], path1) do
					true  -> false
					false -> path1 <= path2 ++ [fname]
				end
		end
 	end
 	defp prefix([], _),             do: true
 	defp prefix([h | t1], [h |t2]), do: prefix(t1, t2)
 	defp prefix(_, _),              do: false
end