Move html templates, support loading templates by format (#2140)

diff --git a/lib/src/html/html_generator.dart b/lib/src/html/html_generator.dart
index 1224005..9178840 100644
--- a/lib/src/html/html_generator.dart
+++ b/lib/src/html/html_generator.dart
@@ -11,7 +11,8 @@
 import 'package:dartdoc/src/generator_frontend.dart';
 import 'package:dartdoc/src/html/html_generator_backend.dart';
 
-Future<Generator> initHtmlGenerator(GeneratorContext context) async {
+Future<Generator> initHtmlGenerator(
+    DartdocGeneratorOptionContext context) async {
   var backend = await HtmlGeneratorBackend.fromContext(context);
   return GeneratorFrontEnd(backend);
 }
diff --git a/lib/src/html/html_generator_backend.dart b/lib/src/html/html_generator_backend.dart
index da0dfb1..b92e39e 100644
--- a/lib/src/html/html_generator_backend.dart
+++ b/lib/src/html/html_generator_backend.dart
@@ -46,7 +46,7 @@
   final Templates _templates;
 
   static Future<HtmlGeneratorBackend> fromContext(
-      GeneratorContext context) async {
+      DartdocGeneratorOptionContext context) async {
     Templates templates = await Templates.fromContext(context);
     // TODO(jcollins-g): Rationalize based on GeneratorContext all the way down
     // through the generators.
diff --git a/lib/src/html/templates.dart b/lib/src/html/templates.dart
index f696ada..1940505 100644
--- a/lib/src/html/templates.dart
+++ b/lib/src/html/templates.dart
@@ -41,25 +41,6 @@
   'accessor_setter',
 ];
 
-const _requiredTemplates = <String>[
-  '404error.html',
-  'category.html',
-  'class.html',
-  'constant.html',
-  'constructor.html',
-  'enum.html',
-  'extension.html',
-  'function.html',
-  'index.html',
-  'library.html',
-  'method.html',
-  'mixin.html',
-  'property.html',
-  'top_level_constant.html',
-  'top_level_property.html',
-  'typedef.html',
-];
-
 const String _headerPlaceholder = '{{! header placeholder }}';
 const String _footerPlaceholder = '{{! footer placeholder }}';
 const String _footerTextPlaceholder = '{{! footer-text placeholder }}';
@@ -97,26 +78,33 @@
   Future<String> loadTemplate(String name);
 }
 
+/// Loads default templates included in the Dartdoc program.
 class _DefaultTemplatesLoader extends _TemplatesLoader {
+  final String _format;
+
+  _DefaultTemplatesLoader(this._format);
+
   @override
   Future<Map<String, String>> loadPartials() async {
     var partials = <String, String>{};
-    for (String partial in _partials) {
-      var uri = 'package:dartdoc/templates/_$partial.html';
-      partials[partial] = await loader.loadAsString(uri);
+    for (String name in _partials) {
+      var uri = 'package:dartdoc/templates/$_format/_$name.$_format';
+      partials[name] = await loader.loadAsString(uri);
     }
     return partials;
   }
 
   @override
   Future<String> loadTemplate(String name) =>
-      loader.loadAsString('package:dartdoc/templates/$name');
+      loader.loadAsString('package:dartdoc/templates/$_format/$name.$_format');
 }
 
+/// Loads templates from a specified Directory.
 class _DirectoryTemplatesLoader extends _TemplatesLoader {
   final Directory _directory;
+  final String _format;
 
-  _DirectoryTemplatesLoader(this._directory);
+  _DirectoryTemplatesLoader(this._directory, this._format);
 
   @override
   Future<Map<String, String>> loadPartials() async {
@@ -124,7 +112,7 @@
 
     for (File file in _directory.listSync().whereType<File>()) {
       var basename = path.basename(file.path);
-      if (basename.startsWith('_') && basename.endsWith('.html')) {
+      if (basename.startsWith('_') && basename.endsWith('.$_format')) {
         var content = file.readAsString();
         var partialName = basename.substring(1, basename.lastIndexOf('.'));
         partials[partialName] = await content;
@@ -135,7 +123,10 @@
 
   @override
   Future<String> loadTemplate(String name) {
-    var file = File(path.join(_directory.path, name));
+    var file = File(path.join(_directory.path, '$name.$_format'));
+    if (!file.existsSync()) {
+      throw DartdocFailure('Missing required template file: $name.$_format');
+    }
     return file.readAsString();
   }
 }
@@ -158,51 +149,41 @@
   final Template topLevelPropertyTemplate;
   final Template typeDefTemplate;
 
-  static Future<Templates> fromContext(GeneratorContext context) {
+  static Future<Templates> fromContext(DartdocGeneratorOptionContext context) {
     String templatesDir = context.templatesDir;
     if (templatesDir != null) {
-      return fromDirectory(Directory(templatesDir),
+      return fromDirectory(Directory(templatesDir), context.format,
           headerPaths: context.header,
           footerPaths: context.footer,
           footerTextPaths: context.footerTextPaths);
     } else {
-      return createDefault(
+      return createDefault(context.format,
           headerPaths: context.header,
           footerPaths: context.footer,
           footerTextPaths: context.footerTextPaths);
     }
   }
 
-  static Future<Templates> createDefault(
+  static Future<Templates> createDefault(String format,
       {List<String> headerPaths,
       List<String> footerPaths,
       List<String> footerTextPaths}) async {
-    return _create(_DefaultTemplatesLoader(),
+    return _create(_DefaultTemplatesLoader(format),
         headerPaths: headerPaths,
         footerPaths: footerPaths,
         footerTextPaths: footerTextPaths);
   }
 
-  static Future<Templates> fromDirectory(Directory dir,
+  static Future<Templates> fromDirectory(Directory dir, String format,
       {List<String> headerPaths,
       List<String> footerPaths,
       List<String> footerTextPaths}) async {
-    await _checkRequiredTemplatesExist(dir);
-    return _create(_DirectoryTemplatesLoader(dir),
+    return _create(_DirectoryTemplatesLoader(dir, format),
         headerPaths: headerPaths,
         footerPaths: footerPaths,
         footerTextPaths: footerTextPaths);
   }
 
-  static void _checkRequiredTemplatesExist(Directory dir) {
-    for (var name in _requiredTemplates) {
-      var file = File(path.join(dir.path, name));
-      if (!file.existsSync()) {
-        throw DartdocFailure('Missing required template file: "$name"');
-      }
-    }
-  }
-
   static Future<Templates> _create(_TemplatesLoader templatesLoader,
       {List<String> headerPaths,
       List<String> footerPaths,
@@ -224,24 +205,22 @@
       return Template(templateContents, partialResolver: _partial);
     }
 
-    var indexTemplate = await _loadTemplate('index.html');
-    var libraryTemplate = await _loadTemplate('library.html');
-    var categoryTemplate = await _loadTemplate('category.html');
-    var classTemplate = await _loadTemplate('class.html');
-    var extensionTemplate = await _loadTemplate('extension.html');
-    var enumTemplate = await _loadTemplate('enum.html');
-    var functionTemplate = await _loadTemplate('function.html');
-    var methodTemplate = await _loadTemplate('method.html');
-    var constructorTemplate = await _loadTemplate('constructor.html');
-    var errorTemplate = await _loadTemplate('404error.html');
-    var propertyTemplate = await _loadTemplate('property.html');
-    var constantTemplate = await _loadTemplate('constant.html');
-    var topLevelConstantTemplate =
-        await _loadTemplate('top_level_constant.html');
-    var topLevelPropertyTemplate =
-        await _loadTemplate('top_level_property.html');
-    var typeDefTemplate = await _loadTemplate('typedef.html');
-    var mixinTemplate = await _loadTemplate('mixin.html');
+    var indexTemplate = await _loadTemplate('index');
+    var libraryTemplate = await _loadTemplate('library');
+    var categoryTemplate = await _loadTemplate('category');
+    var classTemplate = await _loadTemplate('class');
+    var extensionTemplate = await _loadTemplate('extension');
+    var enumTemplate = await _loadTemplate('enum');
+    var functionTemplate = await _loadTemplate('function');
+    var methodTemplate = await _loadTemplate('method');
+    var constructorTemplate = await _loadTemplate('constructor');
+    var errorTemplate = await _loadTemplate('404error');
+    var propertyTemplate = await _loadTemplate('property');
+    var constantTemplate = await _loadTemplate('constant');
+    var topLevelConstantTemplate = await _loadTemplate('top_level_constant');
+    var topLevelPropertyTemplate = await _loadTemplate('top_level_property');
+    var typeDefTemplate = await _loadTemplate('typedef');
+    var mixinTemplate = await _loadTemplate('mixin');
 
     return Templates._(
         indexTemplate,
diff --git a/lib/templates/404error.html b/lib/templates/html/404error.html
similarity index 100%
rename from lib/templates/404error.html
rename to lib/templates/html/404error.html
diff --git a/lib/templates/_accessor_getter.html b/lib/templates/html/_accessor_getter.html
similarity index 100%
rename from lib/templates/_accessor_getter.html
rename to lib/templates/html/_accessor_getter.html
diff --git a/lib/templates/_accessor_setter.html b/lib/templates/html/_accessor_setter.html
similarity index 100%
rename from lib/templates/_accessor_setter.html
rename to lib/templates/html/_accessor_setter.html
diff --git a/lib/templates/_callable.html b/lib/templates/html/_callable.html
similarity index 100%
rename from lib/templates/_callable.html
rename to lib/templates/html/_callable.html
diff --git a/lib/templates/_callable_multiline.html b/lib/templates/html/_callable_multiline.html
similarity index 100%
rename from lib/templates/_callable_multiline.html
rename to lib/templates/html/_callable_multiline.html
diff --git a/lib/templates/_categorization.html b/lib/templates/html/_categorization.html
similarity index 100%
rename from lib/templates/_categorization.html
rename to lib/templates/html/_categorization.html
diff --git a/lib/templates/_class.html b/lib/templates/html/_class.html
similarity index 100%
rename from lib/templates/_class.html
rename to lib/templates/html/_class.html
diff --git a/lib/templates/_constant.html b/lib/templates/html/_constant.html
similarity index 100%
rename from lib/templates/_constant.html
rename to lib/templates/html/_constant.html
diff --git a/lib/templates/_documentation.html b/lib/templates/html/_documentation.html
similarity index 100%
rename from lib/templates/_documentation.html
rename to lib/templates/html/_documentation.html
diff --git a/lib/templates/_extension.html b/lib/templates/html/_extension.html
similarity index 100%
rename from lib/templates/_extension.html
rename to lib/templates/html/_extension.html
diff --git a/lib/templates/_features.html b/lib/templates/html/_features.html
similarity index 100%
rename from lib/templates/_features.html
rename to lib/templates/html/_features.html
diff --git a/lib/templates/_footer.html b/lib/templates/html/_footer.html
similarity index 100%
rename from lib/templates/_footer.html
rename to lib/templates/html/_footer.html
diff --git a/lib/templates/_head.html b/lib/templates/html/_head.html
similarity index 100%
rename from lib/templates/_head.html
rename to lib/templates/html/_head.html
diff --git a/lib/templates/_library.html b/lib/templates/html/_library.html
similarity index 100%
rename from lib/templates/_library.html
rename to lib/templates/html/_library.html
diff --git a/lib/templates/_mixin.html b/lib/templates/html/_mixin.html
similarity index 100%
rename from lib/templates/_mixin.html
rename to lib/templates/html/_mixin.html
diff --git a/lib/templates/_name_summary.html b/lib/templates/html/_name_summary.html
similarity index 100%
rename from lib/templates/_name_summary.html
rename to lib/templates/html/_name_summary.html
diff --git a/lib/templates/_packages.html b/lib/templates/html/_packages.html
similarity index 100%
rename from lib/templates/_packages.html
rename to lib/templates/html/_packages.html
diff --git a/lib/templates/_property.html b/lib/templates/html/_property.html
similarity index 100%
rename from lib/templates/_property.html
rename to lib/templates/html/_property.html
diff --git a/lib/templates/_search_sidebar.html b/lib/templates/html/_search_sidebar.html
similarity index 100%
rename from lib/templates/_search_sidebar.html
rename to lib/templates/html/_search_sidebar.html
diff --git a/lib/templates/_sidebar_for_category.html b/lib/templates/html/_sidebar_for_category.html
similarity index 100%
rename from lib/templates/_sidebar_for_category.html
rename to lib/templates/html/_sidebar_for_category.html
diff --git a/lib/templates/_sidebar_for_class.html b/lib/templates/html/_sidebar_for_class.html
similarity index 100%
rename from lib/templates/_sidebar_for_class.html
rename to lib/templates/html/_sidebar_for_class.html
diff --git a/lib/templates/_sidebar_for_container.html b/lib/templates/html/_sidebar_for_container.html
similarity index 100%
rename from lib/templates/_sidebar_for_container.html
rename to lib/templates/html/_sidebar_for_container.html
diff --git a/lib/templates/_sidebar_for_enum.html b/lib/templates/html/_sidebar_for_enum.html
similarity index 100%
rename from lib/templates/_sidebar_for_enum.html
rename to lib/templates/html/_sidebar_for_enum.html
diff --git a/lib/templates/_sidebar_for_extension.html b/lib/templates/html/_sidebar_for_extension.html
similarity index 100%
rename from lib/templates/_sidebar_for_extension.html
rename to lib/templates/html/_sidebar_for_extension.html
diff --git a/lib/templates/_sidebar_for_library.html b/lib/templates/html/_sidebar_for_library.html
similarity index 100%
rename from lib/templates/_sidebar_for_library.html
rename to lib/templates/html/_sidebar_for_library.html
diff --git a/lib/templates/_source_code.html b/lib/templates/html/_source_code.html
similarity index 100%
rename from lib/templates/_source_code.html
rename to lib/templates/html/_source_code.html
diff --git a/lib/templates/_source_link.html b/lib/templates/html/_source_link.html
similarity index 100%
rename from lib/templates/_source_link.html
rename to lib/templates/html/_source_link.html
diff --git a/lib/templates/category.html b/lib/templates/html/category.html
similarity index 100%
rename from lib/templates/category.html
rename to lib/templates/html/category.html
diff --git a/lib/templates/class.html b/lib/templates/html/class.html
similarity index 100%
rename from lib/templates/class.html
rename to lib/templates/html/class.html
diff --git a/lib/templates/constant.html b/lib/templates/html/constant.html
similarity index 100%
rename from lib/templates/constant.html
rename to lib/templates/html/constant.html
diff --git a/lib/templates/constructor.html b/lib/templates/html/constructor.html
similarity index 100%
rename from lib/templates/constructor.html
rename to lib/templates/html/constructor.html
diff --git a/lib/templates/enum.html b/lib/templates/html/enum.html
similarity index 100%
rename from lib/templates/enum.html
rename to lib/templates/html/enum.html
diff --git a/lib/templates/extension.html b/lib/templates/html/extension.html
similarity index 100%
rename from lib/templates/extension.html
rename to lib/templates/html/extension.html
diff --git a/lib/templates/function.html b/lib/templates/html/function.html
similarity index 100%
rename from lib/templates/function.html
rename to lib/templates/html/function.html
diff --git a/lib/templates/index.html b/lib/templates/html/index.html
similarity index 100%
rename from lib/templates/index.html
rename to lib/templates/html/index.html
diff --git a/lib/templates/library.html b/lib/templates/html/library.html
similarity index 100%
rename from lib/templates/library.html
rename to lib/templates/html/library.html
diff --git a/lib/templates/method.html b/lib/templates/html/method.html
similarity index 100%
rename from lib/templates/method.html
rename to lib/templates/html/method.html
diff --git a/lib/templates/mixin.html b/lib/templates/html/mixin.html
similarity index 100%
rename from lib/templates/mixin.html
rename to lib/templates/html/mixin.html
diff --git a/lib/templates/property.html b/lib/templates/html/property.html
similarity index 100%
rename from lib/templates/property.html
rename to lib/templates/html/property.html
diff --git a/lib/templates/top_level_constant.html b/lib/templates/html/top_level_constant.html
similarity index 100%
rename from lib/templates/top_level_constant.html
rename to lib/templates/html/top_level_constant.html
diff --git a/lib/templates/top_level_property.html b/lib/templates/html/top_level_property.html
similarity index 100%
rename from lib/templates/top_level_property.html
rename to lib/templates/html/top_level_property.html
diff --git a/lib/templates/typedef.html b/lib/templates/html/typedef.html
similarity index 100%
rename from lib/templates/typedef.html
rename to lib/templates/html/typedef.html
diff --git a/test/html_generator_test.dart b/test/html_generator_test.dart
index db62526..a9b87d4 100644
--- a/test/html_generator_test.dart
+++ b/test/html_generator_test.dart
@@ -20,7 +20,8 @@
 
 // Init a generator without a GeneratorContext and with the default file writer.
 Future<Generator> _initGeneratorForTest() async {
-  var backend = HtmlGeneratorBackend(null, await Templates.createDefault());
+  var backend =
+      HtmlGeneratorBackend(null, await Templates.createDefault('html'));
   return GeneratorFrontEnd(backend);
 }
 
@@ -29,7 +30,7 @@
     Templates templates;
 
     setUp(() async {
-      templates = await Templates.createDefault();
+      templates = await Templates.createDefault('html');
     });
 
     test('index html', () {
diff --git a/test/resource_loader_test.dart b/test/resource_loader_test.dart
index 7fc5c3b..2e188d1 100644
--- a/test/resource_loader_test.dart
+++ b/test/resource_loader_test.dart
@@ -10,8 +10,8 @@
 void main() {
   group('Resource Loader', () {
     test('load from packages', () async {
-      var contents =
-          await loader.loadAsString('package:dartdoc/templates/index.html');
+      var contents = await loader
+          .loadAsString('package:dartdoc/templates/html/index.html');
       expect(contents, isNotNull);
     });