Skip to content

Commit 526b359

Browse files
committed
Generate CLI pages automatically
1 parent 096aa8f commit 526b359

1 file changed

Lines changed: 93 additions & 0 deletions

File tree

ddoc_preprocessor.d

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import std.algorithm, std.array, std.ascii, std.conv, std.file, std.format, std.
1818
std.meta, std.path, std.range, std.string, std.typecons;
1919
import std.stdio;
2020

21+
import dmd.cli;
22+
2123
struct Config
2224
{
2325
string dmdBinPath = "dmd";
@@ -53,6 +55,7 @@ All unknown options are passed to the compiler.
5355
text = genGrammar(text);
5456
text = genHeader(text);
5557
text = genChangelogVersion(inputFile, text);
58+
text = genSwitches(text);
5659

5760
// inject custom, "dynamic" macros
5861
text ~= "\nSRC_FILENAME=%s\n".format(inputFile.buildNormalizedPath);
@@ -277,3 +280,93 @@ auto genChangelogVersion(string fileName, string fileText)
277280
}
278281
return fileText;
279282
}
283+
284+
// generate CLI documentation
285+
auto genSwitches(string fileText)
286+
{
287+
enum ddocKey = "$(CLI_SWITCHES";
288+
string content;
289+
foreach (option; Usage.options)
290+
{
291+
string flag = option.flag;
292+
string helpText = option.helpText;
293+
294+
// capitalize the first letter
295+
helpText = helpText.capitalize.to!string;
296+
297+
highlightSpecialWords(flag, helpText);
298+
auto flagEndPos = flag.representation.countUntil("=", "$(", "<");
299+
string switchName;
300+
if (flagEndPos < 0)
301+
switchName = "$(SWNAME -%s)".format(flag);
302+
else
303+
switchName = "$(SWNAME -%s)%s".format(flag[0..flagEndPos], flag[flagEndPos..$]);
304+
305+
auto currentFlag = "$(SWITCH %s,\n
306+
%s
307+
)".format(switchName, helpText);
308+
309+
with(TargetOS)
310+
switch(option.os)
311+
{
312+
case windows:
313+
currentFlag = text("$(WINDOWS ", currentFlag, ")");
314+
break;
315+
case linux:
316+
case macOS:
317+
case freeBSD:
318+
case solaris:
319+
case dragonFlyBSD:
320+
currentFlag = text("$(UNIX ", currentFlag, ")");
321+
break;
322+
case all:
323+
default:
324+
break;
325+
}
326+
content ~= currentFlag;
327+
}
328+
return updateDdocTag(fileText, ddocKey, content);
329+
}
330+
331+
auto italic(string w)
332+
{
333+
return "$(I %s )".format(w);
334+
}
335+
336+
337+
// capitalize the first letter
338+
auto capitalize(string w)
339+
{
340+
import std.range, std.uni;
341+
return w.take(1).asUpperCase.chain(w.dropOne);
342+
}
343+
344+
private void highlightSpecialWords(ref string flag, ref string helpText)
345+
{
346+
if (flag.canFind("<", "[") && flag.canFind(">", "]"))
347+
{
348+
string specialWord;
349+
350+
// detect special words in <...> and highlight them
351+
static foreach (t; [["<", ">"], ["[", "]"]])
352+
{
353+
if (flag.canFind(t[0]))
354+
{
355+
specialWord = flag.findSplit(t[0])[2].until(t[1]).to!string;
356+
// keep []
357+
auto replaceWord = t[0] == "<" ? t[0] ~ specialWord ~ t[1] : specialWord;
358+
flag = flag.replace(replaceWord, specialWord.italic);
359+
}
360+
}
361+
362+
// highlight individual words in the description
363+
helpText = helpText
364+
.splitter(" ")
365+
.map!((w){
366+
auto wPlain = w.filter!(c => !c.among('<', '>', '`', '\'')).to!string;
367+
return wPlain == specialWord ? wPlain.italic: w;
368+
})
369+
.joiner(" ")
370+
.to!string;
371+
}
372+
}

0 commit comments

Comments
 (0)