Moquestra.CodeWriter
2.0.0
dotnet add package Moquestra.CodeWriter --version 2.0.0
NuGet\Install-Package Moquestra.CodeWriter -Version 2.0.0
<PackageReference Include="Moquestra.CodeWriter" Version="2.0.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="Moquestra.CodeWriter" Version="2.0.0" />
<PackageReference Include="Moquestra.CodeWriter"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add Moquestra.CodeWriter --version 2.0.0
#r "nuget: Moquestra.CodeWriter, 2.0.0"
#:package Moquestra.CodeWriter@2.0.0
#addin nuget:?package=Moquestra.CodeWriter&version=2.0.0
#tool nuget:?package=Moquestra.CodeWriter&version=2.0.0
Moquestra.CodeWriter
Source-only text writer for code generation.
CodeBuilder accumulates interpolated strings. Literal text is written as-is,
and a multiline interpolated value is reindented from its second line with the
prefix of the line where the interpolation begins - so a template stays
readable while the generated code keeps its indentation.
var body = "a();\nb();";
var builder = new CodeBuilder();
builder.WriteLine($"void M()");
builder.WriteLine($"{{");
builder.WriteLine($" {body}");
builder.WriteLine($"}}");
void M()
{
a();
b();
}
With C# 11 raw string literals the same template reads like the code it
produces - no escaped braces, no \n:
builder.Write($$"""
void M()
{
{{body}}
}
""");
The prefix is copied verbatim by default, which also works for comment templates:
var summary = "First line.\nSecond line.";
builder.Write($"/// {summary}");
/// First line.
/// Second line.
Installation
NuGet
dotnet add package Moquestra.CodeWriter
The package ships C# source files instead of an assembly. They compile into your
project as internal types, so every consuming assembly gets its own copy and
different versions never collide. The package is a development dependency:
dotnet add package writes PrivateAssets="all" for you, and the reference does
not flow to consumers of your own package.
Copying the sources
Projects that do not use NuGet can copy the sources from a clone of this repository with one of the scripts in the root:
# PowerShell
./copy-source.ps1 -Destination <folder>
# sh
./copy-source.sh <folder>
# cmd
copy-source.bat <folder>
Each script copies the source files verbatim into the folder.
Sharing a copy between assemblies
The types are internal, so a copy is visible only inside the assembly it was
compiled into. To let other assemblies use the same copy, add this to any C#
file in the assembly that holds it:
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("FriendAssembly")]
Usage
Writing
Write(FormattableString)renders the interpolated string and accumulates it.WriteLine()ends the current line;WriteLine(FormattableString)writes and ends the line.ToString()returns everything accumulated so far.
Values that implement IFormattable are rendered with the invariant culture;
other values fall back to ToString(), and null renders as an empty string. A
CodeBuilder can be interpolated into another builder, so fragments compose.
To repeat a template for a sequence of items, render each fragment with its own
CodeBuilder, join the results, and interpolate the joined text. A fragment
built as a plain interpolated string never passes through a builder, so
multiline values inside it are not reindented.
An interpolation hole holds a plain expression. Format and alignment components
inside a hole - {value:X}, {value,-10} - are not supported and throw
FormatException.
Continuation prefixes
Each line of a multiline value after the first receives a continuation prefix
derived from the line where the interpolation began.
PreservedPrefixParts selects which characters of that line are kept verbatim;
the rest are each replaced with a space.
| Value | Prefix "\t- " becomes |
|---|---|
All (default) |
"\t- " |
Tabs |
"\t " |
NonWhitespace |
" - " |
None |
" " |
An empty line, or a line emptied by trimming, keeps the prefix without its
trailing whitespace - so /// continues while indentation does not.
Write(FormattableString, PreservedPrefixParts) overrides the selection for
one call.
Whitespace-only lines
A line that ends holding nothing but spaces and tabs is emptied, whether the
whitespace came from literal text or from a value (TrimWhitespaceOnlyLines,
on by default). The check runs when the line ends, so text appended to an open
line is unaffected.
Settings
CodeBuilderSettings is immutable and groups the output options:
var settings = new CodeBuilderSettings(
newLine: "\r\n", // "\n" (default) or "\r\n"
trimWhitespaceOnlyLines: true, // default
prefixParts: PreservedPrefixParts.All);
var builder = new CodeBuilder(settings);
Input line endings - CRLF, CR and LF - are normalized to the configured newline, in literals and in interpolated values alike.
XML documentation comments
XmlDoc assembles the lines of an XML documentation comment. Tags render in
call order, and ToString() joins the lines with LF and no comment prefix, so
the prefix comes from the template:
var doc = new XmlDoc()
.Summary("Gets the value.")
.Param("id", "The ID to look up.")
.Returns("The value, or null when the ID is unknown.");
builder.Write($"/// {doc}");
/// <summary>Gets the value.</summary>
/// <param name="id">The ID to look up.</param>
/// <returns>The value, or null when the ID is unknown.</returns>
Ten tags are available: Summary, Remarks, Returns, Value, Example,
Param, TypeParam, Exception, InheritDoc and SeeAlso. Text is written
as-is, so inline markup such as <c> and <see cref="..."/> can be embedded;
XmlDoc.Escape escapes a value that must appear literally. Attribute values -
names and cref references - are always escaped.
A text-bearing tag renders inline when its text is a single line and as a
block - opening tag, text lines, closing tag - when it spans several lines. Pass
an XmlDocForm to the constructor to change the default for the document, or
to a tag method to change it for one call:
var doc = new XmlDoc(XmlDocForm.Block)
.Summary("Gets the value.")
.Param("id", "The ID to look up.", XmlDocForm.Inline);
<summary>
Gets the value.
</summary>
<param name="id">The ID to look up.</param>
Requirements
The sources compile with C# 7.3 or later and use only APIs available in .NET Standard 2.0, so they can be added to any project whose target framework supports .NET Standard 2.0. They contain no nullable annotations and compile without warnings whether nullable reference types are enabled or disabled.
Unity
Use one of the copy scripts to place the sources in the folder of the assembly
definition that will use them - usually an Editor assembly - and share the copy
with other assemblies as described above if needed. NuGetForUnity can install the
package too, but it puts the files under Assets/Packages without an assembly
definition, so they compile into Assembly-CSharp, which assembly-definition
based code cannot reference.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.