5
5
library dartdoc.templates;
6
6
7
7
import 'dart:async' show Future;
8
- import 'dart:io' show File;
8
+ import 'dart:io' show File, Directory ;
9
9
10
+ import 'package:dartdoc/dartdoc.dart' ;
10
11
import 'package:dartdoc/src/html/resource_loader.dart' as loader;
11
12
import 'package:mustache/mustache.dart' ;
13
+ import 'package:path/path.dart' as path;
12
14
13
15
const _partials = < String > [
14
16
'callable' ,
@@ -36,50 +38,104 @@ const _partials = <String>[
36
38
'accessor_setter' ,
37
39
];
38
40
39
- Future <Map <String , String >> _loadPartials (List <String > headerPaths,
40
- List <String > footerPaths, List <String > footerTextPaths) async {
41
- final String headerPlaceholder = '<!-- header placeholder -->' ;
42
- final String footerPlaceholder = '<!-- footer placeholder -->' ;
43
- final String footerTextPlaceholder = '<!-- footer-text placeholder -->' ;
41
+ const _requiredTemplates = < String > [
42
+ '404error.html' ,
43
+ 'category.html' ,
44
+ 'class.html' ,
45
+ 'constant.html' ,
46
+ 'constructor.html' ,
47
+ 'enum.html' ,
48
+ 'function.html' ,
49
+ 'index.html' ,
50
+ 'library.html' ,
51
+ 'method.html' ,
52
+ 'mixin.html' ,
53
+ 'property.html' ,
54
+ 'top_level_constant.html' ,
55
+ 'top_level_property.html' ,
56
+ 'typedef.html' ,
57
+ ];
58
+
59
+ const String _headerPlaceholder = '<!-- header placeholder -->' ;
60
+ const String _footerPlaceholder = '<!-- footer placeholder -->' ;
61
+ const String _footerTextPlaceholder = '<!-- footer-text placeholder -->' ;
62
+
63
+ Future <Map <String , String >> _loadPartials (
64
+ _TemplatesLoader templatesLoader,
65
+ List <String > headerPaths,
66
+ List <String > footerPaths,
67
+ List <String > footerTextPaths) async {
44
68
45
69
headerPaths ?? = [];
46
70
footerPaths ?? = [];
47
71
footerTextPaths ?? = [];
48
72
49
- var partials = < String , String > {} ;
73
+ var partials = await templatesLoader. loadPartials () ;
50
74
51
- Future < String > _loadPartial (String templatePath) async {
52
- String template = await _getTemplateFile (templatePath) ;
53
-
54
- if (templatePath. contains ( '_head' )) {
55
- String headerValue =
56
- headerPaths. map ((path) => File (path). readAsStringSync ()). join ( ' \n ' );
57
- template = template. replaceAll (headerPlaceholder, headerValue) ;
75
+ void replacePlaceholder (String key, String placeholder, List < String > paths) {
76
+ var template = partials[key] ;
77
+ if (template != null && paths != null && paths.isNotEmpty) {
78
+ String replacement = paths. map ((p) => File (p). readAsStringSync ())
79
+ . join ( ' \n ' );
80
+ template = template. replaceAll (placeholder, replacement );
81
+ partials[key] = template;
58
82
}
83
+ }
59
84
60
- if (templatePath.contains ('_footer' )) {
61
- String footerValue =
62
- footerPaths.map ((path) => File (path).readAsStringSync ()).join ('\n ' );
63
- template = template.replaceAll (footerPlaceholder, footerValue);
85
+ replacePlaceholder ('head' , _headerPlaceholder, headerPaths);
86
+ replacePlaceholder ('footer' , _footerPlaceholder, footerPaths);
87
+ replacePlaceholder ('footer' , _footerTextPlaceholder, footerTextPaths);
64
88
65
- String footerTextValue = footerTextPaths
66
- .map ((path) => File (path).readAsStringSync ())
67
- .join ('\n ' );
68
- template = template.replaceAll (footerTextPlaceholder, footerTextValue);
69
- }
89
+ return partials;
90
+ }
70
91
71
- return template;
72
- }
92
+ abstract class _TemplatesLoader {
93
+ Future <Map <String , String >> loadPartials ();
94
+ Future <String > loadTemplate (String name);
95
+ }
73
96
74
- for (String partial in _partials) {
75
- partials[partial] = await _loadPartial ('_$partial .html' );
97
+ class _DefaultTemplatesLoader extends _TemplatesLoader {
98
+ @override
99
+ Future <Map <String , String >> loadPartials () async {
100
+ var partials = < String , String > {};
101
+ for (String partial in _partials) {
102
+ var uri = 'package:dartdoc/templates/_$partial .html' ;
103
+ partials[partial] = await loader.loadAsString (uri);
104
+ }
105
+ return partials;
76
106
}
77
107
78
- return partials;
108
+ @override
109
+ Future <String > loadTemplate (String name) =>
110
+ loader.loadAsString ('package:dartdoc/templates/$name ' );
79
111
}
80
112
81
- Future <String > _getTemplateFile (String templateFileName) =>
82
- loader.loadAsString ('package:dartdoc/templates/$templateFileName ' );
113
+ class _DirectoryTemplatesLoader extends _TemplatesLoader {
114
+ final Directory _directory;
115
+
116
+ _DirectoryTemplatesLoader (this ._directory);
117
+
118
+ @override
119
+ Future <Map <String , String >> loadPartials () async {
120
+ var partials = < String , String > {};
121
+
122
+ for (File file in _directory.listSync ().whereType <File >()) {
123
+ var basename = path.basename (file.path);
124
+ if (basename.startsWith ('_' ) && basename.endsWith ('.html' )) {
125
+ var content = file.readAsString ();
126
+ var partialName = basename.substring (1 , basename.lastIndexOf ('.' ));
127
+ partials[partialName] = await content;
128
+ }
129
+ }
130
+ return partials;
131
+ }
132
+
133
+ @override
134
+ Future <String > loadTemplate (String name) {
135
+ var file = File (path.join (_directory.path, name));
136
+ return file.readAsString ();
137
+ }
138
+ }
83
139
84
140
class Templates {
85
141
final Template categoryTemplate;
@@ -98,12 +154,44 @@ class Templates {
98
154
final Template topLevelPropertyTemplate;
99
155
final Template typeDefTemplate;
100
156
101
- static Future <Templates > create (
157
+ static Future <Templates > createDefault (
158
+ {List <String > headerPaths,
159
+ List <String > footerPaths,
160
+ List <String > footerTextPaths}) async {
161
+ return _create (_DefaultTemplatesLoader (),
162
+ headerPaths: headerPaths,
163
+ footerPaths: footerPaths,
164
+ footerTextPaths: footerTextPaths);
165
+ }
166
+
167
+ static Future <Templates > fromDirectory (
168
+ Directory dir,
169
+ {List <String > headerPaths,
170
+ List <String > footerPaths,
171
+ List <String > footerTextPaths}) async {
172
+ await _checkRequiredTemplatesExist (dir);
173
+ return _create (_DirectoryTemplatesLoader (dir),
174
+ headerPaths: headerPaths,
175
+ footerPaths: footerPaths,
176
+ footerTextPaths: footerTextPaths);
177
+ }
178
+
179
+ static void _checkRequiredTemplatesExist (Directory dir) {
180
+ for (var name in _requiredTemplates) {
181
+ var file = File (path.join (dir.path, name));
182
+ if (! file.existsSync ()) {
183
+ throw DartdocFailure ('Missing required template file: "$name "' );
184
+ }
185
+ }
186
+ }
187
+
188
+ static Future <Templates > _create (
189
+ _TemplatesLoader templatesLoader,
102
190
{List <String > headerPaths,
103
191
List <String > footerPaths,
104
192
List <String > footerTextPaths}) async {
105
193
var partials =
106
- await _loadPartials (headerPaths, footerPaths, footerTextPaths);
194
+ await _loadPartials (templatesLoader, headerPaths, footerPaths, footerTextPaths);
107
195
108
196
Template _partial (String name) {
109
197
String partial = partials[name];
@@ -114,7 +202,7 @@ class Templates {
114
202
}
115
203
116
204
Future <Template > _loadTemplate (String templatePath) async {
117
- String templateContents = await _getTemplateFile (templatePath);
205
+ String templateContents = await templatesLoader. loadTemplate (templatePath);
118
206
return Template (templateContents, partialResolver: _partial);
119
207
}
120
208
0 commit comments