Skip to content

Instantly share code, notes, and snippets.

@MarkPflug
Created April 21, 2022 18:01
Show Gist options
  • Save MarkPflug/7daf48757fc9583a5ac37bd7c9428a40 to your computer and use it in GitHub Desktop.
Save MarkPflug/7daf48757fc9583a5ac37bd7c9428a40 to your computer and use it in GitHub Desktop.
IndentingTextWriter for C-style languages
using System.Text;
namespace Sylvan.IO;
sealed class IndentingTextWriter : TextWriter
{
const char OpenChar = '{';
const char CloseChar = '}';
const string DefaultIndent = " ";
readonly TextWriter inner;
int level = 0;
int pending = 0;
bool skipWS = false; //skip user whitespace at the start of lines
string indent;
public IndentingTextWriter(TextWriter inner, string indent = DefaultIndent)
{
this.inner = inner;
this.indent = indent;
}
public override void Flush()
{
inner.Flush();
}
public override Task FlushAsync()
{
return inner.FlushAsync();
}
public override Encoding Encoding => Encoding.UTF8;
public override void Write(char value)
{
if (value == OpenChar)
{
level++;
}
if (value == CloseChar)
{
level--;
pending--;
}
if (skipWS && (value == ' ' || value == '\t'))
{
// skip it
return;
}
else
{
while (pending-- > 0)
{
inner.Write(indent);
}
inner.Write(value);
}
if (value == '\n')
{
pending = level;
skipWS = true;
}
else
{
skipWS = false;
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
inner.Dispose();
}
base.Dispose(disposing);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment