| 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 |