#!/usr/bin/env dub
/+ dub.sdl:
name "ddoc-ies-interaction"
dependency "sparkles:core-cli" path="../.."
dflags "-preview=in" "-preview=dip1000"
+/
/**
Investigation of IES and DDoc `$(DOLLAR)$(LPAREN)...$(RPAREN)` syntax interaction.
Both IES and DDoc use the dollar-paren syntax but for different purposes:
$(UL
$(LI IES: `i"Hello $(DOLLAR)$(LPAREN)name$(RPAREN)"` — interpolation of D expressions)
$(LI DDoc: `$(DOLLAR)$(LPAREN)B bold$(RPAREN)` — macro expansion in documentation)
)
This module tests 8 interaction scenarios to reveal how the compiler
handles `$(DOLLAR)$(LPAREN)...$(RPAREN)` in contexts where both systems could claim it.
# Running This Test
Compile and run:
---
dub run --single docs/guidelines/ddoc_ies_interaction.d
---
Generate DDoc and inspect the HTML output:
---
ldc2 -D -Dd=build/docs -preview=in -preview=dip1000 \
docs/guidelines/ddoc_ies_interaction.d
---
*/
import (package) stdstd.(module) std.convA one-stop shop for converting values from one type to another.
Category Functions Generic asOriginalType castFrom parse to toChars bitCast Strings text wtext dtext writeText writeWText writeDText hexString Numeric octal roundTo signed unsigned Exceptions ConvException ConvOverflowException
Source
std/conv.d
conv : (alias template) ddoc_ies_interaction.text = std.conv.text(T...)(T args) if (T.length > 0)Convenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
import (package) stdstd.(module) std.stdioCategory Symbols File handles _popen File isFileHandle openNetwork stderr stdin stdout Reading chunks lines readf readfln readln Writing toFile write writef writefln writeln Misc KeepTerminator LockType StdioException
Standard I/O functions that extend core.stdc.stdio. core.stdc.stdio
is publically imported when importing std.stdio.
There are three layers of I/O:
The lowest layer is the operating system layer. The two main schemes are Windows and Posix.
C's stdio.h which unifies the two operating system schemes.
std.stdio, this module, unifies the various stdio.h implementations into
a high level package for D programs.
Source
std/stdio.d
stdio : (alias template) ddoc_ies_interaction.writeln = std.stdio.writeln(T...)(T args)Equivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln;
// ---------------------------------------------------------------------------
// Scenario 1: IES in documented unittest
// ---------------------------------------------------------------------------
/**
Scenario 1: IES inside a documented unittest.
When DDoc extracts a documented unittest body as an Example, it processes
the source text through its macro expander. The `$(DOLLAR)$(LPAREN)name$(RPAREN)` inside
`i"Hello $(DOLLAR)$(LPAREN)name$(RPAREN)"` appears as raw text to DDoc.
If `name` is not a defined DDoc macro, it should expand to empty string,
silently vanishing from the Example section in the generated HTML.
Params:
person = the name to greet
Returns: A greeting string.
*/
(alias) object.string = stringstring string ddoc_ies_interaction.greetPerson(string person) pure @safeScenario 1: IES inside a documented unittest.
When DDoc extracts a documented unittest body as an Example, it processes
the source text through its macro expander. The $(name) inside
i"Hello $(name)" appears as raw text to DDoc.
If name is not a defined DDoc macro, it should expand to empty string,
silently vanishing from the Example section in the generated HTML.
Examples
Documented unittest — DDoc extracts this body as an Example.
The `` inside i"..." will be visible to DDoc's macro expander.
string name = "Alice";
auto result = greetPerson(name);
assert(result == "Hello, Alice!");
// This IES literal contains $(name) — DDoc may try to expand it
auto greeting = i"Welcome, $(name)!".text;
assert(greeting == "Welcome, Alice!");
greetPerson((alias) object.string = stringstring (parameter) string personthe name to greet
person) @safe pure
{
return i"Hello, $(person)!".string std.conv.text!(core.interpolation.InterpolationHeader, core.interpolation.InterpolatedLiteral!"Hello, ", core.interpolation.InterpolatedExpression!"person", string, core.interpolation.InterpolatedLiteral!"!", core.interpolation.InterpolationFooter)(core.interpolation.InterpolationHeader __param_0, core.interpolation.InterpolatedLiteral!"Hello, " __param_1, core.interpolation.InterpolatedExpression!"person" __param_2, string __param_3, core.interpolation.InterpolatedLiteral!"!" __param_4, core.interpolation.InterpolationFooter __param_5) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
}
/// Documented unittest — DDoc extracts this body as an Example.
/// The `$(name)` inside `i"..."` will be visible to DDoc's macro expander.
@safe unittest
{
(alias) object.string = stringstring (local variable) string namename = "Alice";
auto (local variable) string resultresult = string ddoc_ies_interaction.greetPerson(string person) pure @safeScenario 1: IES inside a documented unittest.
When DDoc extracts a documented unittest body as an Example, it processes
the source text through its macro expander. The $(name) inside
i"Hello $(name)" appears as raw text to DDoc.
If name is not a defined DDoc macro, it should expand to empty string,
silently vanishing from the Example section in the generated HTML.
Examples
Documented unittest — DDoc extracts this body as an Example.
The `` inside i"..." will be visible to DDoc's macro expander.
string name = "Alice";
auto result = greetPerson(name);
assert(result == "Hello, Alice!");
// This IES literal contains $(name) — DDoc may try to expand it
auto greeting = i"Welcome, $(name)!".text;
assert(greeting == "Welcome, Alice!");
greetPerson((local variable) string namename);
assert((local variable) string resultresult == "Hello, Alice!");
// This IES literal contains $(name) — DDoc may try to expand it
auto (local variable) string greetinggreeting = i"Welcome, $(name)!".string std.conv.text!(core.interpolation.InterpolationHeader, core.interpolation.InterpolatedLiteral!"Welcome, ", core.interpolation.InterpolatedExpression!"name", string, core.interpolation.InterpolatedLiteral!"!", core.interpolation.InterpolationFooter)(core.interpolation.InterpolationHeader __param_0, core.interpolation.InterpolatedLiteral!"Welcome, " __param_1, core.interpolation.InterpolatedExpression!"name" __param_2, string __param_3, core.interpolation.InterpolatedLiteral!"!" __param_4, core.interpolation.InterpolationFooter __param_5) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
assert((local variable) string greetinggreeting == "Welcome, Alice!");
}
// ---------------------------------------------------------------------------
// Scenario 2: IES in `---` code blocks inside DDoc comments
// ---------------------------------------------------------------------------
/**
Scenario 2: IES usage inside a DDoc `---` code block.
Code inside `---` delimiters is NOT subject to DDoc macro expansion.
This means `$(expr)` is preserved literally in the documentation output.
---
int cpu = 75;
string status = "OK";
auto msg = i"CPU: $(cpu)% Status: $(status)".text;
assert(msg == "CPU: 75% Status: OK");
---
The `$(cpu)` and `$(status)` above should appear literally in generated
docs because they are inside a `---` code block.
Params:
cpuPercent = CPU usage percentage
status = current status string
Returns: A formatted status string.
*/
(alias) object.string = stringstring string ddoc_ies_interaction.formatStatus(int cpuPercent, string status) pure @safeScenario 2: IES usage inside a DDoc --- code block.
Code inside --- delimiters is NOT subject to DDoc macro expansion.
This means `` is preserved literally in the documentation output.
int cpu = 75;
string status = "OK";
auto msg = i"CPU: $(cpu)% Status: $(status)".text;
assert(msg == "CPU: 75% Status: OK");
The `` and $(status) above should appear literally in generated
docs because they are inside a --- code block.
Examples
assert(formatStatus(75, "OK") == "CPU: 75% Status: OK");
assert(formatStatus(100, "BUSY") == "CPU: 100% Status: BUSY");
formatStatus(int (parameter) int cpuPercentCPU usage percentage
cpuPercent, (alias) object.string = stringstring (parameter) string statuscurrent status string
status) @safe pure
{
return i"CPU: $(cpuPercent)% Status: $(status)".string std.conv.text!(core.interpolation.InterpolationHeader, core.interpolation.InterpolatedLiteral!"CPU: ", core.interpolation.InterpolatedExpression!"cpuPercent", int, core.interpolation.InterpolatedLiteral!"% Status: ", core.interpolation.InterpolatedExpression!"status", string, core.interpolation.InterpolationFooter)(core.interpolation.InterpolationHeader __param_0, core.interpolation.InterpolatedLiteral!"CPU: " __param_1, core.interpolation.InterpolatedExpression!"cpuPercent" __param_2, int __param_3, core.interpolation.InterpolatedLiteral!"% Status: " __param_4, core.interpolation.InterpolatedExpression!"status" __param_5, string __param_6, core.interpolation.InterpolationFooter __param_7) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
}
///
@safe unittest
{
assert(string ddoc_ies_interaction.formatStatus(int cpuPercent, string status) pure @safeScenario 2: IES usage inside a DDoc --- code block.
Code inside --- delimiters is NOT subject to DDoc macro expansion.
This means `` is preserved literally in the documentation output.
int cpu = 75;
string status = "OK";
auto msg = i"CPU: $(cpu)% Status: $(status)".text;
assert(msg == "CPU: 75% Status: OK");
The `` and $(status) above should appear literally in generated
docs because they are inside a --- code block.
Examples
assert(formatStatus(75, "OK") == "CPU: 75% Status: OK");
assert(formatStatus(100, "BUSY") == "CPU: 100% Status: BUSY");
formatStatus(75, "OK") == "CPU: 75% Status: OK");
assert(string ddoc_ies_interaction.formatStatus(int cpuPercent, string status) pure @safeScenario 2: IES usage inside a DDoc --- code block.
Code inside --- delimiters is NOT subject to DDoc macro expansion.
This means `` is preserved literally in the documentation output.
int cpu = 75;
string status = "OK";
auto msg = i"CPU: $(cpu)% Status: $(status)".text;
assert(msg == "CPU: 75% Status: OK");
The `` and $(status) above should appear literally in generated
docs because they are inside a --- code block.
Examples
assert(formatStatus(75, "OK") == "CPU: 75% Status: OK");
assert(formatStatus(100, "BUSY") == "CPU: 100% Status: BUSY");
formatStatus(100, "BUSY") == "CPU: 100% Status: BUSY");
}
// ---------------------------------------------------------------------------
// Scenario 3: IES in backtick inline code in DDoc prose
// ---------------------------------------------------------------------------
/**
Scenario 3: backtick inline code containing IES syntax.
In DDoc, backtick content is wrapped in `$(DDOC_BACKQUOTED)`, but
macros are still expanded inside backticks.
So writing `i"Hello $(name)"` in prose should cause `$(name)` to be
processed as a macro even inside backticks.
The safe way to show IES in DDoc prose is to use a `---` code block,
or escape: `i"Hello $(DOLLAR)$(LPAREN)name$(RPAREN)"`.
Params:
person = the name to greet
Returns: A greeting string.
*/
(alias) object.string = stringstring string ddoc_ies_interaction.greetSafe(string person) pure @safeScenario 3: backtick inline code containing IES syntax.
In DDoc, backtick content is wrapped in ``, but
macros are still expanded inside backticks.
So writing i"Hello " in prose should cause `` to be
processed as a macro even inside backticks.
The safe way to show IES in DDoc prose is to use a --- code block,
or escape: i"Hello $(name)".
Examples
assert(greetSafe("Bob") == "Greetings, Bob!");
greetSafe((alias) object.string = stringstring (parameter) string personthe name to greet
person) @safe pure
{
return i"Greetings, $(person)!".string std.conv.text!(core.interpolation.InterpolationHeader, core.interpolation.InterpolatedLiteral!"Greetings, ", core.interpolation.InterpolatedExpression!"person", string, core.interpolation.InterpolatedLiteral!"!", core.interpolation.InterpolationFooter)(core.interpolation.InterpolationHeader __param_0, core.interpolation.InterpolatedLiteral!"Greetings, " __param_1, core.interpolation.InterpolatedExpression!"person" __param_2, string __param_3, core.interpolation.InterpolatedLiteral!"!" __param_4, core.interpolation.InterpolationFooter __param_5) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
}
///
@safe unittest
{
assert(string ddoc_ies_interaction.greetSafe(string person) pure @safeScenario 3: backtick inline code containing IES syntax.
In DDoc, backtick content is wrapped in ``, but
macros are still expanded inside backticks.
So writing i"Hello " in prose should cause `` to be
processed as a macro even inside backticks.
The safe way to show IES in DDoc prose is to use a --- code block,
or escape: i"Hello $(name)".
Examples
assert(greetSafe("Bob") == "Greetings, Bob!");
greetSafe("Bob") == "Greetings, Bob!");
}
// ---------------------------------------------------------------------------
// Scenario 4: Bare $(name) in DDoc prose (no backticks, no code block)
// ---------------------------------------------------------------------------
/**
Scenario 4: bare dollar-paren in DDoc prose.
Writing $(name) without backticks or code blocks causes DDoc to
interpret it as a macro invocation. Since `name` is not a defined
DDoc macro, it expands to an empty string.
Compare these in generated docs:
$(UL
$(LI $(B This text is bold) — `B` is a predefined DDoc macro)
$(LI $(I This text is italic) — `I` is a predefined DDoc macro)
$(LI >$(name)< — undefined macro, should vanish)
$(LI >$(DOLLAR)$(LPAREN)name$(RPAREN)< — escaped, shows literal text)
)
Params:
person = the name to greet
Returns: A farewell string.
*/
(alias) object.string = stringstring string ddoc_ies_interaction.farewell(string person) pure @safeScenario 4: bare dollar-paren in DDoc prose.
Writing without backticks or code blocks causes DDoc to
interpret it as a macro invocation. Since name is not a defined
DDoc macro, it expands to an empty string.
Compare these in generated docs:
This text is bold — B is a predefined DDoc macro
This text is italic — I is a predefined DDoc macro
< — undefined macro, should vanish
$(name)< — escaped, shows literal text
Examples
assert(farewell("Charlie") == "Goodbye, Charlie!");
farewell((alias) object.string = stringstring (parameter) string personthe name to greet
person) @safe pure
{
return i"Goodbye, $(person)!".string std.conv.text!(core.interpolation.InterpolationHeader, core.interpolation.InterpolatedLiteral!"Goodbye, ", core.interpolation.InterpolatedExpression!"person", string, core.interpolation.InterpolatedLiteral!"!", core.interpolation.InterpolationFooter)(core.interpolation.InterpolationHeader __param_0, core.interpolation.InterpolatedLiteral!"Goodbye, " __param_1, core.interpolation.InterpolatedExpression!"person" __param_2, string __param_3, core.interpolation.InterpolatedLiteral!"!" __param_4, core.interpolation.InterpolationFooter __param_5) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
}
///
@safe unittest
{
assert(string ddoc_ies_interaction.farewell(string person) pure @safeScenario 4: bare dollar-paren in DDoc prose.
Writing without backticks or code blocks causes DDoc to
interpret it as a macro invocation. Since name is not a defined
DDoc macro, it expands to an empty string.
Compare these in generated docs:
This text is bold — B is a predefined DDoc macro
This text is italic — I is a predefined DDoc macro
< — undefined macro, should vanish
$(name)< — escaped, shows literal text
Examples
assert(farewell("Charlie") == "Goodbye, Charlie!");
farewell("Charlie") == "Goodbye, Charlie!");
}
// ---------------------------------------------------------------------------
// Scenario 5: DDoc macros coexisting with IES in function body
// ---------------------------------------------------------------------------
/**
Scenario 5: DDoc macros in comments, IES in function body.
This function uses $(LREF greetPerson) internally. The $(D formatReport)
function demonstrates that DDoc macros in comments and IES in the
function body coexist without conflict.
DDoc processes comments only — it never looks inside function bodies.
The IES `$(DOLLAR)$(LPAREN)count$(RPAREN)` in the body is invisible to DDoc.
Params:
person = the person to include in the report
count = the item count to report
Returns: A formatted report string.
See_Also: $(LREF greetPerson), $(LREF formatStatus)
*/
(alias) object.string = stringstring string ddoc_ies_interaction.formatReport(string person, int count) pure @safeScenario 5: DDoc macros in comments, IES in function body.
This function uses greetPerson internally. The formatReport
function demonstrates that DDoc macros in comments and IES in the
function body coexist without conflict.
DDoc processes comments only — it never looks inside function bodies.
The IES $(count) in the body is invisible to DDoc.
Examples
assert(formatReport("Dave", 5) == "Report: Dave has 5 items");
formatReport((alias) object.string = stringstring (parameter) string personthe person to include in the report
person, int (parameter) int countthe item count to report
count) @safe pure
{
auto (local variable) string greetinggreeting = i"$(person) has $(count) items".string std.conv.text!(core.interpolation.InterpolationHeader, core.interpolation.InterpolatedExpression!"person", string, core.interpolation.InterpolatedLiteral!" has ", core.interpolation.InterpolatedExpression!"count", int, core.interpolation.InterpolatedLiteral!" items", core.interpolation.InterpolationFooter)(core.interpolation.InterpolationHeader __param_0, core.interpolation.InterpolatedExpression!"person" __param_1, string __param_2, core.interpolation.InterpolatedLiteral!" has " __param_3, core.interpolation.InterpolatedExpression!"count" __param_4, int __param_5, core.interpolation.InterpolatedLiteral!" items" __param_6, core.interpolation.InterpolationFooter __param_7) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
return i"Report: $(greeting)".string std.conv.text!(core.interpolation.InterpolationHeader, core.interpolation.InterpolatedLiteral!"Report: ", core.interpolation.InterpolatedExpression!"greeting", string, core.interpolation.InterpolationFooter)(core.interpolation.InterpolationHeader __param_0, core.interpolation.InterpolatedLiteral!"Report: " __param_1, core.interpolation.InterpolatedExpression!"greeting" __param_2, string __param_3, core.interpolation.InterpolationFooter __param_4) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
}
///
@safe unittest
{
assert(string ddoc_ies_interaction.formatReport(string person, int count) pure @safeScenario 5: DDoc macros in comments, IES in function body.
This function uses greetPerson internally. The formatReport
function demonstrates that DDoc macros in comments and IES in the
function body coexist without conflict.
DDoc processes comments only — it never looks inside function bodies.
The IES $(count) in the body is invisible to DDoc.
Examples
assert(formatReport("Dave", 5) == "Report: Dave has 5 items");
formatReport("Dave", 5) == "Report: Dave has 5 items");
}
// ---------------------------------------------------------------------------
// Scenario 6: Dollar sign escaping
// ---------------------------------------------------------------------------
/**
Scenario 6: dollar sign escaping in IES vs DDoc.
In IES, `\$` produces a literal dollar sign:
---
string price = i"Price: \$$(amount)".text;
// With amount=42: "Price: $42"
---
In DDoc, use `$(DOLLAR)` for a literal dollar sign:
$(UL
$(LI Literal dollar: $(DOLLAR))
$(LI Literal dollar-paren: $(DOLLAR)$(LPAREN))
$(LI Literal right paren: $(RPAREN))
)
To show IES syntax literally in DDoc prose, write
`$(DOLLAR)$(LPAREN)expr$(RPAREN)` which renders as the literal text.
Params:
amount = the price amount
Returns: A price string with dollar sign.
*/
(alias) object.string = stringstring string ddoc_ies_interaction.formatPrice(int amount) pure @safeScenario 6: dollar sign escaping in IES vs DDoc.
In IES, \$ produces a literal dollar sign:
string price = i"Price: \$$(amount)".text;
// With amount=42: "Price: $42"
In DDoc, use $ for a literal dollar sign:
Literal dollar: $
Literal dollar-paren: $(
Literal right paren: )
To show IES syntax literally in DDoc prose, write
$(expr) which renders as the literal text.
Examples
assert(formatPrice(42) == "Price: $42");
assert(formatPrice(0) == "Price: $0");
formatPrice(int (parameter) int amountthe price amount
amount) @safe pure
{
return i"Price: \$$(amount)".string std.conv.text!(core.interpolation.InterpolationHeader, core.interpolation.InterpolatedLiteral!"Price: $", core.interpolation.InterpolatedExpression!"amount", int, core.interpolation.InterpolationFooter)(core.interpolation.InterpolationHeader __param_0, core.interpolation.InterpolatedLiteral!"Price: $" __param_1, core.interpolation.InterpolatedExpression!"amount" __param_2, int __param_3, core.interpolation.InterpolationFooter __param_4) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
}
///
@safe unittest
{
assert(string ddoc_ies_interaction.formatPrice(int amount) pure @safeScenario 6: dollar sign escaping in IES vs DDoc.
In IES, \$ produces a literal dollar sign:
string price = i"Price: \$$(amount)".text;
// With amount=42: "Price: $42"
In DDoc, use $ for a literal dollar sign:
Literal dollar: $
Literal dollar-paren: $(
Literal right paren: )
To show IES syntax literally in DDoc prose, write
$(expr) which renders as the literal text.
Examples
assert(formatPrice(42) == "Price: $42");
assert(formatPrice(0) == "Price: $0");
formatPrice(42) == "Price: $42");
assert(string ddoc_ies_interaction.formatPrice(int amount) pure @safeScenario 6: dollar sign escaping in IES vs DDoc.
In IES, \$ produces a literal dollar sign:
string price = i"Price: \$$(amount)".text;
// With amount=42: "Price: $42"
In DDoc, use $ for a literal dollar sign:
Literal dollar: $
Literal dollar-paren: $(
Literal right paren: )
To show IES syntax literally in DDoc prose, write
$(expr) which renders as the literal text.
Examples
assert(formatPrice(42) == "Price: $42");
assert(formatPrice(0) == "Price: $0");
formatPrice(0) == "Price: $0");
}
// ---------------------------------------------------------------------------
// Scenario 7: Nested IES in documented unittests
// ---------------------------------------------------------------------------
/**
Scenario 7: nested IES in documented unittests.
Chained IES conversions produce multiple `$(DOLLAR)$(LPAREN)...$(RPAREN)` patterns
in the unittest source text. When DDoc extracts this as an Example,
its parenthesis-tracking macro expander encounters nested dollar-paren
sequences from multiple IES literals.
*/
(alias) object.string = stringstring string ddoc_ies_interaction.nestedIes() pure @safeScenario 7: nested IES in documented unittests.
Chained IES conversions produce multiple $(...) patterns
in the unittest source text. When DDoc extracts this as an Example,
its parenthesis-tracking macro expander encounters nested dollar-paren
sequences from multiple IES literals.
Examples
Documented unittest with chained IES expressions.
DDoc will see multiple $(...) patterns in the extracted source.
int val = 42;
auto inner = i"inner=$(val)".text;
auto result = i"outer[$(inner)]".text;
assert(result == "outer[inner=42]");
// Chained IES conversions
string name = "Eve";
int count = 3;
auto part1 = i"$(name):".text;
auto part2 = i"$(part1) $(count) items".text;
assert(part2 == "Eve: 3 items");
nestedIes() @safe pure
{
int (local variable) int valval = 42;
auto (local variable) string innerinner = i"inner=$(val)".string std.conv.text!(core.interpolation.InterpolationHeader, core.interpolation.InterpolatedLiteral!"inner=", core.interpolation.InterpolatedExpression!"val", int, core.interpolation.InterpolationFooter)(core.interpolation.InterpolationHeader __param_0, core.interpolation.InterpolatedLiteral!"inner=" __param_1, core.interpolation.InterpolatedExpression!"val" __param_2, int __param_3, core.interpolation.InterpolationFooter __param_4) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
return i"outer[$(inner)]".string std.conv.text!(core.interpolation.InterpolationHeader, core.interpolation.InterpolatedLiteral!"outer[", core.interpolation.InterpolatedExpression!"inner", string, core.interpolation.InterpolatedLiteral!"]", core.interpolation.InterpolationFooter)(core.interpolation.InterpolationHeader __param_0, core.interpolation.InterpolatedLiteral!"outer[" __param_1, core.interpolation.InterpolatedExpression!"inner" __param_2, string __param_3, core.interpolation.InterpolatedLiteral!"]" __param_4, core.interpolation.InterpolationFooter __param_5) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
}
/// Documented unittest with chained IES expressions.
/// DDoc will see multiple `$(...)` patterns in the extracted source.
@safe unittest
{
int (local variable) int valval = 42;
auto (local variable) string innerinner = i"inner=$(val)".string std.conv.text!(core.interpolation.InterpolationHeader, core.interpolation.InterpolatedLiteral!"inner=", core.interpolation.InterpolatedExpression!"val", int, core.interpolation.InterpolationFooter)(core.interpolation.InterpolationHeader __param_0, core.interpolation.InterpolatedLiteral!"inner=" __param_1, core.interpolation.InterpolatedExpression!"val" __param_2, int __param_3, core.interpolation.InterpolationFooter __param_4) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
auto (local variable) string resultresult = i"outer[$(inner)]".string std.conv.text!(core.interpolation.InterpolationHeader, core.interpolation.InterpolatedLiteral!"outer[", core.interpolation.InterpolatedExpression!"inner", string, core.interpolation.InterpolatedLiteral!"]", core.interpolation.InterpolationFooter)(core.interpolation.InterpolationHeader __param_0, core.interpolation.InterpolatedLiteral!"outer[" __param_1, core.interpolation.InterpolatedExpression!"inner" __param_2, string __param_3, core.interpolation.InterpolatedLiteral!"]" __param_4, core.interpolation.InterpolationFooter __param_5) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
assert((local variable) string resultresult == "outer[inner=42]");
// Chained IES conversions
(alias) object.string = stringstring (local variable) string namename = "Eve";
int (local variable) int countcount = 3;
auto (local variable) string part1part1 = i"$(name):".string std.conv.text!(core.interpolation.InterpolationHeader, core.interpolation.InterpolatedExpression!"name", string, core.interpolation.InterpolatedLiteral!":", core.interpolation.InterpolationFooter)(core.interpolation.InterpolationHeader __param_0, core.interpolation.InterpolatedExpression!"name" __param_1, string __param_2, core.interpolation.InterpolatedLiteral!":" __param_3, core.interpolation.InterpolationFooter __param_4) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
auto (local variable) string part2part2 = i"$(part1) $(count) items".string std.conv.text!(core.interpolation.InterpolationHeader, core.interpolation.InterpolatedExpression!"part1", string, core.interpolation.InterpolatedLiteral!" ", core.interpolation.InterpolatedExpression!"count", int, core.interpolation.InterpolatedLiteral!" items", core.interpolation.InterpolationFooter)(core.interpolation.InterpolationHeader __param_0, core.interpolation.InterpolatedExpression!"part1" __param_1, string __param_2, core.interpolation.InterpolatedLiteral!" " __param_3, core.interpolation.InterpolatedExpression!"count" __param_4, int __param_5, core.interpolation.InterpolatedLiteral!" items" __param_6, core.interpolation.InterpolationFooter __param_7) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
assert((local variable) string part2part2 == "Eve: 3 items");
}
// ---------------------------------------------------------------------------
// Scenario 8: IES with expressions that look like DDoc macros
// ---------------------------------------------------------------------------
/**
Scenario 8: variable names that collide with DDoc macro names.
The variables `B`, `D`, and `I` are valid D identifiers, but
`$(B text)` is the DDoc bold macro, `$(D code)` is inline code,
and `$(I text)` is italic.
In a documented unittest, DDoc extracts source text and applies
macro expansion. The text `i"$(B)"` contains `$(B)` which DDoc
will interpret as the bold macro with empty content.
*/
(alias) object.string = stringstring string ddoc_ies_interaction.ambiguousNames() pure @safeScenario 8: variable names that collide with DDoc macro names.
The variables B, D, and I are valid D identifiers, but
**text** is the DDoc bold macro, code is inline code,
and *text* is italic.
In a documented unittest, DDoc extracts source text and applies
macro expansion. The text i"****" contains **** which DDoc
will interpret as the bold macro with empty content.
Examples
Documented unittest where variable names match DDoc macro names.
In generated docs, ****, ````, and ** in the IES literals
may be expanded as DDoc macros instead of appearing as source code.
string B = "bold-value";
string D = "code-value";
string I = "italic-value";
// These IES expressions use variables named B, D, I
// which are also DDoc macro names
auto result = i"B=$(B) D=$(D) I=$(I)".text;
assert(result == "B=bold-value D=code-value I=italic-value");
// Single-letter variable that is NOT a DDoc macro
string X = "x-value";
auto safe = i"X=$(X)".text;
assert(safe == "X=x-value");
ambiguousNames() @safe pure
{
(alias) object.string = stringstring (local variable) string BB = "bold-var";
(alias) object.string = stringstring (local variable) string DD = "code-var";
(alias) object.string = stringstring (local variable) string II = "italic-var";
return i"B=$(B) D=$(D) I=$(I)".string std.conv.text!(core.interpolation.InterpolationHeader, core.interpolation.InterpolatedLiteral!"B=", core.interpolation.InterpolatedExpression!"B", string, core.interpolation.InterpolatedLiteral!" D=", core.interpolation.InterpolatedExpression!"D", string, core.interpolation.InterpolatedLiteral!" I=", core.interpolation.InterpolatedExpression!"I", string, core.interpolation.InterpolationFooter)(core.interpolation.InterpolationHeader __param_0, core.interpolation.InterpolatedLiteral!"B=" __param_1, core.interpolation.InterpolatedExpression!"B" __param_2, string __param_3, core.interpolation.InterpolatedLiteral!" D=" __param_4, core.interpolation.InterpolatedExpression!"D" __param_5, string __param_6, core.interpolation.InterpolatedLiteral!" I=" __param_7, core.interpolation.InterpolatedExpression!"I" __param_8, string __param_9, core.interpolation.InterpolationFooter __param_10) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
}
/// Documented unittest where variable names match DDoc macro names.
/// In generated docs, `$(B)`, `$(D)`, and `$(I)` in the IES literals
/// may be expanded as DDoc macros instead of appearing as source code.
@safe unittest
{
(alias) object.string = stringstring (local variable) string BB = "bold-value";
(alias) object.string = stringstring (local variable) string DD = "code-value";
(alias) object.string = stringstring (local variable) string II = "italic-value";
// These IES expressions use variables named B, D, I
// which are also DDoc macro names
auto (local variable) string resultresult = i"B=$(B) D=$(D) I=$(I)".string std.conv.text!(core.interpolation.InterpolationHeader, core.interpolation.InterpolatedLiteral!"B=", core.interpolation.InterpolatedExpression!"B", string, core.interpolation.InterpolatedLiteral!" D=", core.interpolation.InterpolatedExpression!"D", string, core.interpolation.InterpolatedLiteral!" I=", core.interpolation.InterpolatedExpression!"I", string, core.interpolation.InterpolationFooter)(core.interpolation.InterpolationHeader __param_0, core.interpolation.InterpolatedLiteral!"B=" __param_1, core.interpolation.InterpolatedExpression!"B" __param_2, string __param_3, core.interpolation.InterpolatedLiteral!" D=" __param_4, core.interpolation.InterpolatedExpression!"D" __param_5, string __param_6, core.interpolation.InterpolatedLiteral!" I=" __param_7, core.interpolation.InterpolatedExpression!"I" __param_8, string __param_9, core.interpolation.InterpolationFooter __param_10) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
assert((local variable) string resultresult == "B=bold-value D=code-value I=italic-value");
// Single-letter variable that is NOT a DDoc macro
(alias) object.string = stringstring (local variable) string XX = "x-value";
auto (local variable) string safesafe = i"X=$(X)".string std.conv.text!(core.interpolation.InterpolationHeader, core.interpolation.InterpolatedLiteral!"X=", core.interpolation.InterpolatedExpression!"X", string, core.interpolation.InterpolationFooter)(core.interpolation.InterpolationHeader __param_0, core.interpolation.InterpolatedLiteral!"X=" __param_1, core.interpolation.InterpolatedExpression!"X" __param_2, string __param_3, core.interpolation.InterpolationFooter __param_4) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
assert((local variable) string safesafe == "X=x-value");
}
// ---------------------------------------------------------------------------
// Main — run all scenarios and print results
// ---------------------------------------------------------------------------
void void D main()main()
{
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("=== IES / DDoc Interaction Test ===");
void std.stdio.writeln!()() @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln();
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("--- Scenario 1: IES in documented unittest ---");
void std.stdio.writeln!(string, string)(string __param_0, string __param_1) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln(" greetPerson(\"Alice\") = ", string ddoc_ies_interaction.greetPerson(string person) pure @safeScenario 1: IES inside a documented unittest.
When DDoc extracts a documented unittest body as an Example, it processes
the source text through its macro expander. The $(name) inside
i"Hello $(name)" appears as raw text to DDoc.
If name is not a defined DDoc macro, it should expand to empty string,
silently vanishing from the Example section in the generated HTML.
Examples
Documented unittest — DDoc extracts this body as an Example.
The `` inside i"..." will be visible to DDoc's macro expander.
string name = "Alice";
auto result = greetPerson(name);
assert(result == "Hello, Alice!");
// This IES literal contains $(name) — DDoc may try to expand it
auto greeting = i"Welcome, $(name)!".text;
assert(greeting == "Welcome, Alice!");
greetPerson("Alice"));
void std.stdio.writeln!()() @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln();
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("--- Scenario 2: IES in ---code block--- documented function ---");
void std.stdio.writeln!(string, string)(string __param_0, string __param_1) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln(" formatStatus(75, \"OK\") = ", string ddoc_ies_interaction.formatStatus(int cpuPercent, string status) pure @safeScenario 2: IES usage inside a DDoc --- code block.
Code inside --- delimiters is NOT subject to DDoc macro expansion.
This means `` is preserved literally in the documentation output.
int cpu = 75;
string status = "OK";
auto msg = i"CPU: $(cpu)% Status: $(status)".text;
assert(msg == "CPU: 75% Status: OK");
The `` and $(status) above should appear literally in generated
docs because they are inside a --- code block.
Examples
assert(formatStatus(75, "OK") == "CPU: 75% Status: OK");
assert(formatStatus(100, "BUSY") == "CPU: 100% Status: BUSY");
formatStatus(75, "OK"));
void std.stdio.writeln!()() @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln();
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("--- Scenario 3: IES in backtick-documented function ---");
void std.stdio.writeln!(string, string)(string __param_0, string __param_1) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln(" greetSafe(\"Bob\") = ", string ddoc_ies_interaction.greetSafe(string person) pure @safeScenario 3: backtick inline code containing IES syntax.
In DDoc, backtick content is wrapped in ``, but
macros are still expanded inside backticks.
So writing i"Hello " in prose should cause `` to be
processed as a macro even inside backticks.
The safe way to show IES in DDoc prose is to use a --- code block,
or escape: i"Hello $(name)".
Examples
assert(greetSafe("Bob") == "Greetings, Bob!");
greetSafe("Bob"));
void std.stdio.writeln!()() @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln();
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("--- Scenario 4: Bare $(name) in DDoc prose ---");
void std.stdio.writeln!(string, string)(string __param_0, string __param_1) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln(" farewell(\"Charlie\") = ", string ddoc_ies_interaction.farewell(string person) pure @safeScenario 4: bare dollar-paren in DDoc prose.
Writing without backticks or code blocks causes DDoc to
interpret it as a macro invocation. Since name is not a defined
DDoc macro, it expands to an empty string.
Compare these in generated docs:
This text is bold — B is a predefined DDoc macro
This text is italic — I is a predefined DDoc macro
< — undefined macro, should vanish
$(name)< — escaped, shows literal text
Examples
assert(farewell("Charlie") == "Goodbye, Charlie!");
farewell("Charlie"));
void std.stdio.writeln!()() @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln();
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("--- Scenario 5: DDoc macros + IES body ---");
void std.stdio.writeln!(string, string)(string __param_0, string __param_1) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln(" formatReport(\"Dave\", 5) = ", string ddoc_ies_interaction.formatReport(string person, int count) pure @safeScenario 5: DDoc macros in comments, IES in function body.
This function uses greetPerson internally. The formatReport
function demonstrates that DDoc macros in comments and IES in the
function body coexist without conflict.
DDoc processes comments only — it never looks inside function bodies.
The IES $(count) in the body is invisible to DDoc.
Examples
assert(formatReport("Dave", 5) == "Report: Dave has 5 items");
formatReport("Dave", 5));
void std.stdio.writeln!()() @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln();
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("--- Scenario 6: Dollar sign escaping ---");
void std.stdio.writeln!(string, string)(string __param_0, string __param_1) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln(" formatPrice(42) = ", string ddoc_ies_interaction.formatPrice(int amount) pure @safeScenario 6: dollar sign escaping in IES vs DDoc.
In IES, \$ produces a literal dollar sign:
string price = i"Price: \$$(amount)".text;
// With amount=42: "Price: $42"
In DDoc, use $ for a literal dollar sign:
Literal dollar: $
Literal dollar-paren: $(
Literal right paren: )
To show IES syntax literally in DDoc prose, write
$(expr) which renders as the literal text.
Examples
assert(formatPrice(42) == "Price: $42");
assert(formatPrice(0) == "Price: $0");
formatPrice(42));
void std.stdio.writeln!()() @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln();
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("--- Scenario 7: Nested IES ---");
void std.stdio.writeln!(string, string)(string __param_0, string __param_1) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln(" nestedIes() = ", string ddoc_ies_interaction.nestedIes() pure @safeScenario 7: nested IES in documented unittests.
Chained IES conversions produce multiple $(...) patterns
in the unittest source text. When DDoc extracts this as an Example,
its parenthesis-tracking macro expander encounters nested dollar-paren
sequences from multiple IES literals.
Examples
Documented unittest with chained IES expressions.
DDoc will see multiple $(...) patterns in the extracted source.
int val = 42;
auto inner = i"inner=$(val)".text;
auto result = i"outer[$(inner)]".text;
assert(result == "outer[inner=42]");
// Chained IES conversions
string name = "Eve";
int count = 3;
auto part1 = i"$(name):".text;
auto part2 = i"$(part1) $(count) items".text;
assert(part2 == "Eve: 3 items");
nestedIes());
void std.stdio.writeln!()() @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln();
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("--- Scenario 8: DDoc macro-like variable names ---");
void std.stdio.writeln!(string, string)(string __param_0, string __param_1) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln(" ambiguousNames() = ", string ddoc_ies_interaction.ambiguousNames() pure @safeScenario 8: variable names that collide with DDoc macro names.
The variables B, D, and I are valid D identifiers, but
**text** is the DDoc bold macro, code is inline code,
and *text* is italic.
In a documented unittest, DDoc extracts source text and applies
macro expansion. The text i"****" contains **** which DDoc
will interpret as the bold macro with empty content.
Examples
Documented unittest where variable names match DDoc macro names.
In generated docs, ****, ````, and ** in the IES literals
may be expanded as DDoc macros instead of appearing as source code.
string B = "bold-value";
string D = "code-value";
string I = "italic-value";
// These IES expressions use variables named B, D, I
// which are also DDoc macro names
auto result = i"B=$(B) D=$(D) I=$(I)".text;
assert(result == "B=bold-value D=code-value I=italic-value");
// Single-letter variable that is NOT a DDoc macro
string X = "x-value";
auto safe = i"X=$(X)".text;
assert(safe == "X=x-value");
ambiguousNames());
void std.stdio.writeln!()() @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln();
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("=== All runtime tests passed ===");
void std.stdio.writeln!()() @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln();
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("To generate DDoc and inspect the interaction:");
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln(" ldc2 -D -Dd=build/docs -preview=in -preview=dip1000 \\");
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln(" docs/guidelines/ddoc_ies_interaction.d");
}