Nest.Text
1.0.3
dotnet add package Nest.Text --version 1.0.3
NuGet\Install-Package Nest.Text -Version 1.0.3
<PackageReference Include="Nest.Text" Version="1.0.3" />
<PackageVersion Include="Nest.Text" Version="1.0.3" />
<PackageReference Include="Nest.Text" />
paket add Nest.Text --version 1.0.3
#r "nuget: Nest.Text, 1.0.3"
#:package Nest.Text@1.0.3
#addin nuget:?package=Nest.Text&version=1.0.3
#tool nuget:?package=Nest.Text&version=1.0.3
Nest.Text
Nest.Text is a zero-dependency, fluent structured text generation library that helps you build structured content with ease — from C#, Python, and YAML to HTML, XML, and more. It lets you describe what to generate — Nest takes care of how it's formatted.
🔗 Links
- 📦 NuGet: Nest.Text on NuGet
- 💻 GitHub: github.com/h-shahzaib/Nest.Text
Quick Navigation
- Installation
- Core API
- Line Break Behavior
- Configuration Options
- Character Replacement
- Reusing Builder Patterns
- Examples
- Debugging
Installation
dotnet add package Nest.Text
What Is It?
Nest.Text provides a builder-style API to generate code, markup, or any structured text using:
.L(...)
– Write one or more lines.B(b => { })
– Begin a block with nested content.L(...).B(b => { })
– Write a logical group of content
Nest adds or avoids line breaks based on chaining and structure awareness.
Line Break Behavior
Understanding how line breaks work with different usage patterns:
Usage Patterns
Lines
_.L("one");
_.L("two");
_.L("one");
_.L("two");
- ❌ No line break will be added between these lines
Multiple Lines
✅ Line break will be added here
_.L(
"one",
"two"
);
✅ Line break will be added here
_.L("one");
_.L("two");
Multi-Line raw string literal
✅ Line break will be added here
_.L(
"""
one
two
"""
);
✅ Line break will be added here
_.L(
"""
one
two
"""
);
✅ Line break will be added here
Strings having line breaks
✅ Line break will be added here
_.L("one \n two");
_.L(); ⚠️ First explicit line break will override implicit line break
_.L(); ✅ Explicit line break will be added here
_.L("one \n two");
✅ Line break will be added here
Method Chaining
✅ Line break will be added here
_.L("one")
.L("two").B(_ =>
{
_.L("three");
});
✅ Line break will be added here
- ❌ No line break between chained calls
Options
_.Options.BlockStyle = BlockStyle.CurlyBraces; // Choose between 'CurlyBraces' or 'IndentOnly' (default)
_.Options.IndentChar = ' '; // Character used for indentation (e.g., space or tab)
_.Options.IndentSize = 4; // Number of indent characters per level
Live Behavior & Inheritance
Options
in Nest.Text are live — changes apply immediately and affect all content added after the change.
Live Indent Example
_.L("Console.WriteLine(`A`)"); // uses current indent size (e.g. 4)
_.Options.IndentSize = 0;
_.L("Console.WriteLine(`B`)"); // will have no indentation
_.Options.IndentSize = 4;
_.L("Console.WriteLine(`C`)"); // will again be indented
Each line reflects the indent size active at the time it's written.
Character Replacement
You can register characters to be replaced with other characters:
_.Options.RegisterCharReplacement('`', '"');
And then use backticks (`) instead of escaped quotes in your strings:
_.L("Console.WriteLine(`Hello World!`);");
// Outputs: Console.WriteLine("Hello World!");
BlockStyle
Changing the BlockStyle will, by default, apply the new style to all blocks, including nested ones.
_.L("namespace Demo").B(_ =>
{
_.L("class A").B(_ =>
{
_.L("void Print()").B(_ =>
{
_.L("print(`Hello`)");
});
});
_.Options.BlockStyle = BlockStyle.CurlyBraces;
_.L("class A").B(_ =>
{
_.L("void Print()").B(_ =>
{
_.L("print(`Hello`)");
});
});
});
✅ all blocks after the change inside namespace Demo
will use CurlyBraces
.
Reusing Common Builder Patterns
Since .B()
accepts a lambda, you can pass a method that takes an ITextBuilder
parameter — this lets you keep the structure clean by moving code blocks into reusable methods.
✅ Example: Extracting an If-Else Block
Instead of writing everything inline:
_.L("if (count > 6)").B(_ =>
{
_.L("Console.WriteLine(`Hello World!`);");
_.L("Console.WriteLine(`Hello Again!`);");
})
.L("else").B(_ =>
{
_.L("Console.WriteLine(`Hello World!`);");
});
You can extract it into a separate method:
void AddIfElse(ITextBuilder _)
{
_.L("if (count > 6)").B(_ =>
{
_.L("Console.WriteLine(`Hello World!`);");
_.L("Console.WriteLine(`Hello Again!`);");
})
.L("else").B(_ =>
{
_.L("Console.WriteLine(`Hello World!`);");
});
}
And call it like this:
_.L("public static void Main(string[] args)").B(_ => AddIfElse(_));
✅ This keeps the Main
method block clean and readable.
Using .Append()
.Append()
allows you to insert multiple external methods cleanly:
_.L("public static void Main(string[] args)").B(_ =>
_.Append(_ => AddIfElse(_)).Append(_ => AddLoop(_))
);
Each method AddIfElse()
, AddLoop()
still receives the same builder instance, so indentation and formatting stay consistent.
Using .Chain()
If you're inside a chain, use .Chain()
and pass a method that takes IChainBuilder
:
void AddMainBody(IChainBuilder _)
{
_.B(_ =>
{
_.L("if (count > 6)").B(_ =>
{
_.L("Console.WriteLine(`Hello World!`);");
})
.L("else").B(_ =>
{
_.L("Console.WriteLine(`Goodbye!`);");
});
});
}
Then call it like:
_.L("public static void Main(string[] args)")
.Chain(_ => AddMainBody(_));
Why?
- ✅ Keeps your generation logic modular.
- ✅ Makes complex structures easier to read and maintain.
- ✅ Allows mixing and matching reusable blocks.
This approach is especially helpful when generating large sections like methods, conditionals, loops, or class structures.
Examples
Below are a few examples of how you can generate code for different languages:
#️⃣ C# Example (CurlyBraces)
var _ = TextBuilder.Create();
_.Options.BlockStyle = BlockStyle.CurlyBraces;
_.Options.IndentSize = 4;
_.Options.IndentChar = ' ';
_.L("using System.Text;");
_.L("namespace MyProgram").B(_ =>
{
_.L("public class MyProgram").B(_ =>
{
_.L("public static void Main(string[] args)").B(_ =>
{
_.L("if (count > 6)").B(_ =>
{
_.L("Console.WriteLine(`Hello World!`);");
_.L("Console.WriteLine(`Hello Again!`);");
})
.L("else").B(_ =>
{
_.L("Console.WriteLine(`Hello World!`);");
});
});
});
});
Console.WriteLine(_.ToString());
🐍 Python Example (IndentOnly)
var _ = TextBuilder.Create();
_.Options.BlockStyle = BlockStyle.IndentOnly;
_.Options.IndentSize = 4;
_.Options.IndentChar = ' ';
_.L("def greet():").B(_ =>
{
_.L("print(`Hello World!`)");
_.L("print(`Hello Again!`)");
});
Console.WriteLine(_.ToString());
🌐 HTML Example
var _ = TextBuilder.Create();
_.Options.BlockStyle = BlockStyle.IndentOnly;
_.Options.IndentSize = 2;
_.Options.IndentChar = ' ';
_.L("<div>").B(_ =>
{
_.L("<span>Hello World!</span>");
_.L("<span>Hello Again!</span>");
}
).L("</div>");
Console.WriteLine(_.ToString());
📄 XML Example
var _ = TextBuilder.Create();
_.Options.BlockStyle = BlockStyle.IndentOnly;
_.Options.IndentSize = 4;
_.Options.IndentChar = ' ';
_.L("<config>").B(_ =>
{
_.L("<entry key=`theme`>dark</entry>");
_.L("<entry key=`lang`>en</entry>");
}
).L("</config>");
Console.WriteLine(_.ToString());
📘 YAML Example
var _ = TextBuilder.Create();
_.Options.BlockStyle = BlockStyle.IndentOnly;
_.Options.IndentSize = 4;
_.Options.IndentChar = ' ';
_.L("library:").B(_ =>
{
_.L("name: `Nest`");
_.L("use: `Structured Text Generation`");
_.L("features:").B(_ =>
{
_.L("- Automated Indentation");
_.L("- Easy To Use");
_.L("- Zero Dependency");
});
});
Console.WriteLine(_.ToString());
Debugging
You can inspect the builder at any point during generation:
_.L("if (count > 0)").B(_ =>
{
_.L("Console.WriteLine(`Positive`);");
Console.WriteLine("--- Debug Snapshot ---");
Console.WriteLine(_.ToString()); // View current generated output
});
Alternatively, set a breakpoint anywhere and inspect the builder in your debugger. This is especially useful when checking structure, indentation, or formatting mid-flow.
Since everything is standard C#, you can step through and verify behavior interactively — no custom tooling needed.
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.