@@ -18,6 +18,8 @@ import std.algorithm, std.array, std.ascii, std.conv, std.file, std.format, std.
18
18
std.meta , std.path , std.range , std.string , std.typecons ;
19
19
import std.stdio ;
20
20
21
+ import dmd.cli;
22
+
21
23
struct Config
22
24
{
23
25
string dmdBinPath = " dmd" ;
@@ -53,6 +55,7 @@ All unknown options are passed to the compiler.
53
55
text = genGrammar(text);
54
56
text = genHeader(text);
55
57
text = genChangelogVersion(inputFile, text);
58
+ text = genSwitches(text);
56
59
57
60
// inject custom, "dynamic" macros
58
61
text ~= " \n SRC_FILENAME=%s\n " .format(inputFile.buildNormalizedPath);
@@ -277,3 +280,95 @@ auto genChangelogVersion(string fileName, string fileText)
277
280
}
278
281
return fileText;
279
282
}
283
+
284
+ // generate CLI documentation
285
+ auto genSwitches (string fileText)
286
+ {
287
+ enum ddocKey = " $(CLI_SWITCHES" ;
288
+ auto content = ddocKey ~ " \n " ;
289
+ foreach (option; Usage.options)
290
+ {
291
+ string flag = option.flag;
292
+ string helpText = option.helpText;
293
+ if (! option.ddocText.empty)
294
+ helpText = option.ddocText;
295
+
296
+ // capitalize the first letter
297
+ helpText = helpText.capitalize.to! string ;
298
+
299
+ highlightSpecialWords(flag, helpText);
300
+ auto flagEndPos = flag.representation.countUntil(" =" , " $(" , " <" );
301
+ string switchName;
302
+ if (flagEndPos < 0 )
303
+ switchName = " $(SWNAME -%s)" .format(flag);
304
+ else
305
+ switchName = " $(SWNAME -%s)%s" .format(flag[0 .. flagEndPos], flag[flagEndPos.. $]);
306
+
307
+ auto currentFlag = " $(SWITCH %s,\n
308
+ %s
309
+ )" .format(switchName, helpText);
310
+
311
+ with (TargetOS)
312
+ switch (option.os)
313
+ {
314
+ case windows:
315
+ currentFlag = text(" $(WINDOWS " , currentFlag, " )" );
316
+ break ;
317
+ case linux:
318
+ case macOS:
319
+ case freeBSD:
320
+ case solaris:
321
+ case dragonFlyBSD:
322
+ currentFlag = text(" $(UNIX " , currentFlag, " )" );
323
+ break ;
324
+ case all:
325
+ default :
326
+ break ;
327
+ }
328
+ content ~= currentFlag;
329
+ }
330
+ return updateDdocTag (fileText, ddocKey, content);
331
+ }
332
+
333
+ auto italic (string w)
334
+ {
335
+ return " $(I %s )" .format(w);
336
+ }
337
+
338
+
339
+ // capitalize the first letter
340
+ auto capitalize (string w)
341
+ {
342
+ import std.range , std.uni ;
343
+ return w.take(1 ).asUpperCase.chain(w.dropOne);
344
+ }
345
+
346
+ private void highlightSpecialWords (ref string flag, ref string helpText)
347
+ {
348
+ if (flag.canFind(" <" , " [" ) && flag.canFind(" >" , " ]" ))
349
+ {
350
+ string specialWord;
351
+
352
+ // detect special words in <...> and highlight them
353
+ static foreach (t; [[" <" , " >" ], [" [" , " ]" ]])
354
+ {
355
+ if (flag.canFind(t[0 ]))
356
+ {
357
+ specialWord = flag.findSplit(t[0 ])[2 ].until(t[1 ]).to! string ;
358
+ // keep []
359
+ auto replaceWord = t[0 ] == " <" ? t[0 ] ~ specialWord ~ t[1 ] : specialWord;
360
+ flag = flag.replace(replaceWord, specialWord.italic);
361
+ }
362
+ }
363
+
364
+ // highlight individual words in the description
365
+ helpText = helpText
366
+ .splitter(" " )
367
+ .map! ((w){
368
+ auto wPlain = w.filter! (c => ! c.among(' <' , ' >' , ' `' , ' \' ' )).to! string ;
369
+ return wPlain == specialWord ? wPlain.italic: w;
370
+ })
371
+ .joiner(" " )
372
+ .to! string ;
373
+ }
374
+ }
0 commit comments