A Drop-in Indented TextWriter in C#
source link: https://www.codeproject.com/Tips/5315915/A-Drop-in-Indented-TextWriter-in-Csharp
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Introduction
I was recently writing a code generator using some of my old code from Rolex - a powerful multilanguage code generator that creates tokenizers/lexers given input specifications files that consist of a series of named regular expressions.
That tool uses something called the CodeDOM to do most of the heavy lifting in terms of code formatting, but these days I'm about simplifying, and I don't need the CodeDOM and its ability to render code in multiple languages. I don't use Visual Basic so it seems kind of silly to go through all of the work of supporting it when someone can just link it as a library. So now I'm writing code out directly in C# instead. It's faster, but it leaves me missing some things, among them automatic code formatting.
This doesn't do automatic code formatting, but it does make it so I, or more the the point, you - can easily indent blocks of code, or otherwise sections of text, like XML, HTML, or anything where indentation is important.
Using the code
Using the code involves dropping the following class wholesale into a new file in your code. Rather than provide a download, the entire implemention is simple enough to just provide here:
using System; using System.IO; using System.Text; // quick and dirty indented text writer // by honey the codewitch class IndentedTextWriter : TextWriter { bool _needIndent; TextWriter _writer; public IndentedTextWriter(TextWriter writer) { if (writer == null) throw new ArgumentNullException(); _writer = writer; _needIndent = false; } public override Encoding Encoding => _writer.Encoding; public override void Write(char value) { if(_needIndent) { _writer.Write(_Indent(IndentLevel)); _needIndent = false; } if (value == '\n') { _needIndent = true; _writer.Write("\n"); } else _writer.Write(value); } public int IndentLevel { get; set; } = 0; public string Indent { get; set; } = " "; string _Indent(int level) { if (level<=0) return ""; var len = level * Indent.Length; var sb = new StringBuilder(len, len) ; for(var i = 0;i<level;++i) { sb.Append(Indent); } return sb.ToString(); } }
Using it goes something like the following, which was adapted from an actual application of mine (in progress):
// create an text writer over the console var tw = new IndentedTextWriter(Console.Out); // write out "namespace {codenamespace} if // codenamespace was specified if(!string.IsNullOrEmpty(codenamespace)) { tw.WriteLine("namespace {0}", codenamespace); tw.WriteLine("{"); // increase the indent level for all // subsequent writes ++tw.IndentLevel; } // this will be indented compared to the // namespace declaration: CodeGenerator.GenerateCodeAttribute(tw); tw.WriteLine("partial class {0}", codeclass); tw.WriteLine("{"); // increase the indent again ++tw.IndentLevel; // generate a method CodeGenerator.GenerateUnicodeFetchMethod(tw); // decrease the indent to close the class --tw.IndentLevel; tw.WriteLine("}"); // if necessary decrease the indent and // close the namespace if (!string.IsNullOrEmpty(codenamespace)) { --tw.IndentLevel; tw.WriteLine("}"); }
As I said, the above code was adapted from an actual application. It's not all shown here, but enough is shown to illustrate how to use the IndentedTextWriter
class.
Notice above we're just writing things out, and then we can increase the indent by manipulating IndentLevel
. You can also change the string used as the indent by modifying the Indent
property, which defaults to four spaces. Once the IndentLevel
is modified, subsequent writes proceed at that level, allowing you to transparently indent portions of the written document. Above you can see that if codenamespace
is specified, only then does the rest of the code get indented, and then we can simply pass the IndentedTextWriter
around like a regular TextWriter
and anything that writes to it will write out at that indentation level. I haven't tested nesting it by creating an IndentedTextWriter
over another IndentedTextWriter
, but in theory that should work, too in case you need that.
I hope this solves a thing for you.
History
23rd October, 2021 - Initial submission
Recommend
-
66
vim-disapprove-deep-indentation This Vim plugin disapproves deeply indented code.
-
75
README.md Text2MindMap An online tool for making mindmaps by writing indented lists. A few months ago one of my favorite tools Text2MindMap went...
-
44
Contribute to pianohacker/vim-indented-paragraph development by creating an account on GitHub.
-
27
Turn asterisk-indented text lines into mind maps. Contribute to lucasepe/crumbs development by creating an account on GitHub.
-
3
How to create an indented block in Python? advertisements for example, how to I enter this in Python so that it is indented correctly?
-
9
Files Permalink Latest commit message Commit time
-
9
Indented Results Roll Out at 40% of SERPsSearch EnginesRecently, after m...
-
3
Print layout of a python dict, i.e. only keys and the types of the values (in case of nested dict's an indented dict is printed). · GitHub Instantly share code, notes, and snippets. ...
-
2
-
13
Search Engine Land » SEO » Case study: Are indented search results on Google actually h...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK