OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * To generate docs for a library, run this script with the path to an | 6 * To generate docs for a library, run this script with the path to an |
7 * entrypoint .dart file, like: | 7 * entrypoint .dart file, like: |
8 * | 8 * |
9 * $ dart dartdoc.dart foo.dart | 9 * $ dart dartdoc.dart foo.dart |
10 * | 10 * |
11 * This will create a "docs" directory with the docs for your libraries. To | 11 * This will create a "docs" directory with the docs for your libraries. To |
12 * create these beautiful docs, dartdoc parses your library and every library | 12 * create these beautiful docs, dartdoc parses your library and every library |
13 * it imports (recursively). From each library, it parses all classes and | 13 * it imports (recursively). From each library, it parses all classes and |
14 * members, finds the associated doc comments and builds crosslinked docs from | 14 * members, finds the associated doc comments and builds crosslinked docs from |
15 * them. | 15 * them. |
16 */ | 16 */ |
17 #library('dartdoc'); | 17 #library('dartdoc'); |
18 | 18 |
19 #import('dart:io'); | 19 #import('dart:io'); |
20 | 20 |
21 // TODO(rnystrom): Use "package:" URL (#4968). | 21 // TODO(rnystrom): Use "package:" URL (#4968). |
22 #import('../lib/dartdoc.dart'); | 22 #import('../lib/dartdoc.dart'); |
| 23 #import('../../args/lib/args.dart'); |
23 | 24 |
24 /** | 25 /** |
25 * Run this from the `pkg/dartdoc` directory. | 26 * Run this from the `pkg/dartdoc` directory. |
26 */ | 27 */ |
27 main() { | 28 main() { |
| 29 // Need this because ArgParser.getUsage doesn't show command invocation. |
| 30 final USAGE = 'Usage dartdoc [options] <entrypoint(s)>\n[options] include:'; |
| 31 |
28 final args = new Options().arguments; | 32 final args = new Options().arguments; |
29 | 33 |
30 final dartdoc = new Dartdoc(); | 34 final dartdoc = new Dartdoc(); |
| 35 |
| 36 final argParser = new ArgParser(); |
| 37 |
| 38 argParser.addFlag('no-code', |
| 39 help: 'Do not include source code in the documentation.', |
| 40 defaultsTo: false, negatable: false, |
| 41 callback: (noCode) => dartdoc.includeSource = !noCode); |
| 42 |
| 43 argParser.addOption('mode', abbr: 'm', |
| 44 help: 'Define how HTML pages are generated.', |
| 45 allowed: ['static', 'live-nav'], allowedHelp: { |
| 46 'static': 'Generates completely static HTML containing\n' |
| 47 'everything you need to browse the docs. The only\n' |
| 48 'client side behavior is trivial stuff like syntax\n' |
| 49 'highlighting code, and the find-as-you-type search\n' |
| 50 'box.', |
| 51 'live-nav': '(Default) Generated docs do not included baked HTML\n' |
| 52 'navigation. Instead a single `nav.json` file is\n' |
| 53 'created and the appropriate navigation is generated\n' |
| 54 'client-side by parsing that and building HTML.\n' |
| 55 '\tThis dramatically reduces the generated size of\n' |
| 56 'the HTML since a large fraction of each static page\n' |
| 57 'is just redundant navigation links.\n' |
| 58 '\tIn this mode, the browser will do a XHR for\n' |
| 59 'nav.json which means that to preview docs locallly,\n' |
| 60 'you will need to enable requesting file:// links in\n' |
| 61 'your browser or run a little local server like\n' |
| 62 '`python -m SimpleHTTPServer`.'}, |
| 63 defaultsTo: 'live-nav', |
| 64 callback: (genMode) { |
| 65 dartdoc.mode = (genMode == 'static' ? MODE_STATIC : MODE_LIVE_NAV); |
| 66 }); |
| 67 |
| 68 argParser.addFlag('generate-app-cache', |
| 69 help: 'Generates the App Cache manifest file, enabling\n' |
| 70 'offline doc viewing.', |
| 71 defaultsTo: false, negatable: false, |
| 72 callback: (generate) => dartdoc.generateAppCache = generate); |
| 73 |
| 74 argParser.addFlag('omit-generation-time', |
| 75 help: 'Omits generation timestamp from output.', |
| 76 defaultsTo: false, negatable: false, |
| 77 callback: (genTimestamp) => dartdoc.omitGenerationTime = genTimestamp); |
| 78 |
| 79 argParser.addFlag('verbose', abbr: 'v', |
| 80 help: 'Print verbose information during generation.', |
| 81 defaultsTo: false, negatable: false, |
| 82 callback: (verb) => dartdoc.verbose = verb); |
| 83 |
| 84 argParser.addFlag('include-api', |
| 85 help: 'Include the used API libraries in the generated\n' |
| 86 'documentation. If the --link-api option is used,\n' |
| 87 'this option is ignored.', |
| 88 defaultsTo: false, negatable: false, |
| 89 callback: (incApi) => dartdoc.includeApi = incApi); |
| 90 |
| 91 argParser.addFlag('link-api', |
| 92 help: 'Link to the online language API in the generated\n' |
| 93 'documentation. The option overrides inclusion\n' |
| 94 'through --include-api or --include-lib.', |
| 95 defaultsTo: false, negatable: false, |
| 96 callback: (linkApi) => dartdoc.linkToApi = linkApi); |
| 97 |
| 98 argParser.addFlag('enable-diagnostic-colors', negatable: false); |
| 99 |
| 100 argParser.addOption('out', |
| 101 help: 'Generates files into directory specified. If\n' |
| 102 'omitted the files are generated into ./docs/', |
| 103 callback: (outDir) { |
| 104 if(outDir != null) { |
| 105 dartdoc.outputDir = new Path.fromNative(outDir); |
| 106 } |
| 107 }); |
| 108 |
| 109 argParser.addOption('include-lib', |
| 110 help: 'Use this option to explicitly specify which\n' |
| 111 'libraries to include in the documentation. If\n' |
| 112 'omitted, all used libraries are included by\n' |
| 113 'default. Specify a comma-separated list of\n' |
| 114 'library names, or call this option multiple times.', |
| 115 callback: (incLibs) { |
| 116 if(!incLibs.isEmpty()) { |
| 117 List<String> allLibs = new List<String>(); |
| 118 for(final lst in incLibs) { |
| 119 var someLibs = lst.split(','); |
| 120 for(final lib in someLibs) { |
| 121 allLibs.add(lib); |
| 122 } |
| 123 } |
| 124 dartdoc.excludedLibraries = allLibs; |
| 125 } |
| 126 }, allowMultiple: true); |
| 127 |
| 128 argParser.addOption('exclude-lib', |
| 129 help: 'Use this option to explicitly specify which\n' |
| 130 'libraries to exclude from the documentation. If\n' |
| 131 'omitted, no libraries are excluded. Specify a\n' |
| 132 'comma-separated list of library names, or call\n' |
| 133 'this option multiple times.', |
| 134 callback: (excLibs) { |
| 135 if(!excLibs.isEmpty()) { |
| 136 List<String> allLibs = new List<String>(); |
| 137 for(final lst in excLibs) { |
| 138 var someLibs = lst.split(','); |
| 139 for(final lib in someLibs) { |
| 140 allLibs.add(lib); |
| 141 } |
| 142 } |
| 143 dartdoc.excludedLibraries = allLibs; |
| 144 } |
| 145 }, allowMultiple: true); |
31 | 146 |
32 final libPath = scriptDir.append('../../../'); | 147 final libPath = scriptDir.append('../../../'); |
33 dartdoc.dartdocPath = libPath.append('pkg/dartdoc'); | 148 dartdoc.dartdocPath = libPath.append('pkg/dartdoc'); |
34 | 149 |
35 if (args.isEmpty()) { | 150 if (args.isEmpty()) { |
36 print('No arguments provided.'); | 151 print('No arguments provided.'); |
37 printUsage(); | 152 print(USAGE); |
| 153 print(argParser.getUsage()); |
38 return; | 154 return; |
39 } | 155 } |
40 | 156 |
41 final entrypoints = <Path>[]; | 157 final entrypoints = <Path>[]; |
42 | 158 try { |
43 var i = 0; | 159 final option = argParser.parse(args); |
44 while (i < args.length) { | 160 for(final arg in option.rest) { |
45 final arg = args[i]; | 161 entrypoints.add(new Path.fromNative(arg)); |
46 if (!arg.startsWith('--')) { | 162 } |
47 // The remaining arguments must be entry points. | 163 } on FormatException catch (e) { |
48 break; | 164 print(e.message); |
49 } | 165 print(USAGE); |
50 | 166 print(argParser.getUsage()); |
51 switch (arg) { | 167 return; |
52 case '--no-code': | |
53 dartdoc.includeSource = false; | |
54 break; | |
55 | |
56 case '--mode=static': | |
57 dartdoc.mode = MODE_STATIC; | |
58 break; | |
59 | |
60 case '--mode=live-nav': | |
61 dartdoc.mode = MODE_LIVE_NAV; | |
62 break; | |
63 | |
64 case '--generate-app-cache': | |
65 case '--generate-app-cache=true': | |
66 dartdoc.generateAppCache = true; | |
67 break; | |
68 | |
69 case '--omit-generation-time': | |
70 dartdoc.omitGenerationTime = true; | |
71 break; | |
72 case '--verbose': | |
73 dartdoc.verbose = true; | |
74 break; | |
75 case '--include-api': | |
76 dartdoc.includeApi = true; | |
77 break; | |
78 case '--link-api': | |
79 dartdoc.linkToApi = true; | |
80 break; | |
81 | |
82 // Hack to accept, but not use, colors option. | |
83 // This allows shared bash script to run dartdoc. | |
84 case '--enable-diagnostic-colors': | |
85 break; | |
86 | |
87 default: | |
88 if (arg.startsWith('--out=')) { | |
89 dartdoc.outputDir = | |
90 new Path.fromNative(arg.substring('--out='.length)); | |
91 } else if (arg.startsWith('--include-lib=')) { | |
92 dartdoc.includedLibraries = | |
93 arg.substring('--include-lib='.length).split(','); | |
94 } else if (arg.startsWith('--exclude-lib=')) { | |
95 dartdoc.excludedLibraries = | |
96 arg.substring('--exclude-lib='.length).split(','); | |
97 } else { | |
98 print('Unknown option: $arg'); | |
99 printUsage(); | |
100 return; | |
101 } | |
102 break; | |
103 } | |
104 i++; | |
105 } | |
106 while (i < args.length) { | |
107 final arg = args[i]; | |
108 entrypoints.add(new Path.fromNative(arg)); | |
109 i++; | |
110 } | 168 } |
111 | 169 |
112 if (entrypoints.isEmpty()) { | 170 if (entrypoints.isEmpty()) { |
113 print('No entrypoints provided.'); | 171 print('No entrypoints provided.'); |
114 printUsage(); | 172 print(USAGE); |
| 173 print(argParser.getUsage()); |
115 return; | 174 return; |
116 } | 175 } |
117 | 176 |
118 cleanOutputDirectory(dartdoc.outputDir); | 177 cleanOutputDirectory(dartdoc.outputDir); |
119 | 178 |
120 dartdoc.documentLibraries(entrypoints, libPath); | 179 dartdoc.documentLibraries(entrypoints, libPath); |
121 | 180 |
122 Future compiled = compileScript(dartdoc.mode, dartdoc.outputDir, libPath); | 181 Future compiled = compileScript(dartdoc.mode, dartdoc.outputDir, libPath); |
123 Future filesCopied = copyDirectory(scriptDir.append('../static'), | 182 Future filesCopied = copyDirectory(scriptDir.append('../static'), |
124 dartdoc.outputDir); | 183 dartdoc.outputDir); |
125 | 184 |
126 Futures.wait([compiled, filesCopied]).then((_) { | 185 Futures.wait([compiled, filesCopied]).then((_) { |
127 dartdoc.cleanup(); | 186 dartdoc.cleanup(); |
128 print('Documented ${dartdoc.totalLibraries} libraries, ' | 187 print('Documented ${dartdoc.totalLibraries} libraries, ' |
129 '${dartdoc.totalTypes} types, and ${dartdoc.totalMembers} members.'); | 188 '${dartdoc.totalTypes} types, and ${dartdoc.totalMembers} members.'); |
130 }); | 189 }); |
131 } | 190 } |
132 | |
133 void printUsage() { | |
134 print(''' | |
135 Usage dartdoc [options] <entrypoint(s)> | |
136 [options] include | |
137 --no-code Do not include source code in the documentation. | |
138 | |
139 --mode=static Generates completely static HTML containing | |
140 everything you need to browse the docs. The only | |
141 client side behavior is trivial stuff like syntax | |
142 highlighting code. | |
143 | |
144 --mode=live-nav (default) Generated docs do not include baked HTML | |
145 navigation. Instead, a single `nav.json` file is | |
146 created and the appropriate navigation is generated | |
147 client-side by parsing that and building HTML. | |
148 This dramatically reduces the generated size of | |
149 the HTML since a large fraction of each static page | |
150 is just redundant navigation links. | |
151 In this mode, the browser will do a XHR for | |
152 nav.json which means that to preview docs locally, | |
153 you will need to enable requesting file:// links in | |
154 your browser or run a little local server like | |
155 `python -m SimpleHTTPServer`. | |
156 | |
157 --generate-app-cache Generates the App Cache manifest file, enabling | |
158 offline doc viewing. | |
159 | |
160 --out=<dir> Generates files into directory <dir>. If omitted | |
161 the files are generated into ./docs/ | |
162 | |
163 --link-api Link to the online language API in the generated | |
164 documentation. The option overrides inclusion | |
165 through --include-api or --include-lib. | |
166 | |
167 --include-api Include the used API libraries in the generated | |
168 documentation. If the --link-api option is used, | |
169 this option is ignored. | |
170 | |
171 --include-lib=<libs> Use this option to explicitly specify which | |
172 libraries to include in the documentation. If | |
173 omitted, all used libraries are included by | |
174 default. <libs> is comma-separated list of library | |
175 names. | |
176 | |
177 --exclude-lib=<libs> Use this option to explicitly specify which | |
178 libraries to exclude from the documentation. If | |
179 omitted, no libraries are excluded. <libs> is | |
180 comma-separated list of library names. | |
181 | |
182 --verbose Print verbose information during generation. | |
183 '''); | |
184 } | |
OLD | NEW |