Skip to content

Instantly share code, notes, and snippets.

@robfe
Created June 26, 2010 15:07
Show Gist options
  • Save robfe/454117 to your computer and use it in GitHub Desktop.
Save robfe/454117 to your computer and use it in GitHub Desktop.
Extract #regions into individual txt files for INCLUDETEXT in word...
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Regionator
{
public class Program
{
const int TargetSpacesPerIndent = 3;
const int SourceSpacesPerIndent = 4;
static readonly object ConsoleLockObject = new object();
static void Main(string[] args)
{
string targetDir = args.FirstOrDefault() ?? Environment.CurrentDirectory;
if (!Directory.Exists(targetDir))
{
Console.Out.WriteLine(targetDir + "is not a valid directory!");
Environment.Exit(-1);
}
targetDir = Path.GetFullPath(targetDir);
var files = Directory.GetFiles(targetDir, "*.cs", SearchOption.AllDirectories);
Console.Out.WriteLine("Found {0} cs files", files.Count());
var regions = from f in files.AsParallel()
from r in GetRegions(File.ReadLines(f))
select new { Filename = f.Substring(targetDir.Length), Region = r };
regions.ForAll(x => SaveFile(GetFileName(x.Filename, x.Region.Name), x.Region.Text));
}
static void SaveFile(string fileName, string text)
{
string oldValue = File.Exists(fileName) ? File.ReadAllText(fileName) : null;
lock (ConsoleLockObject)
{
Console.Write(fileName);
if (oldValue != null)
{
if (oldValue == text)
{
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.WriteLine(" No Change");
}
else
{
int delta = text.Length - oldValue.Length;
Console.Write(" ");
Console.ForegroundColor = delta == 0 ? ConsoleColor.White : delta < 0 ? ConsoleColor.DarkRed : ConsoleColor.Green;
if (delta >= 0)
{
Console.Write("+");
}
Console.WriteLine(delta + " chars");
}
}
else
{
Console.ForegroundColor = ConsoleColor.Magenta;
Console.WriteLine(" New File");
}
Console.ResetColor();
}
File.WriteAllText(fileName, text);
}
static string GetFileName(string sourceFilename, string regionName)
{
char c = Path.DirectorySeparatorChar;
var src = sourceFilename.TrimStart(c).Replace(c, '_');
return String.Format("{0}-{1}.txt", src, regionName);
}
public static IEnumerable<Region> GetRegions(IEnumerable<string> lines)
{
List<Region> completedRegions = new List<Region>();
Stack<Region> workingRegions = new Stack<Region>();
foreach (var line in lines)
{
string trimmedLine = line.TrimStart();
if (trimmedLine.StartsWith("#region"))
{
var text = trimmedLine.Substring("#region".Length);
workingRegions.Push(new Region(text));
}
else if (trimmedLine.StartsWith("#endregion"))
{
completedRegions.Add(workingRegions.Pop());
}
else
{
foreach (var region in workingRegions)
{
region.Lines.Add(line);
}
}
}
// make the region's names unique per file
foreach (var group in completedRegions.GroupBy(x => x.Name))
{
int i = 2;
foreach (var r in group.Skip(1))
{
r.Name += " (" + i + ")";
i++;
}
}
return completedRegions;
}
public class Region
{
static readonly string SourceIndentTabReplacement = new string(' ', SourceSpacesPerIndent);
public Region(string text)
{
Name = text.Trim();
Lines = new List<string>();
}
public string Name { get; set; }
public List<string> Lines { get; private set; }
public string Text
{
get
{
var lines = Lines.SkipWhile(string.IsNullOrWhiteSpace).Reverse().SkipWhile(string.IsNullOrWhiteSpace).Reverse();
//replace tabs with 4 spaces
lines = lines.Select(x => x.Replace("\t", SourceIndentTabReplacement));
//now turn indentlevel to 3 space-per-tab
lines = from line in lines
let indent = line.TakeWhile(char.IsWhiteSpace).Count()
select new string(' ', indent / SourceSpacesPerIndent * TargetSpacesPerIndent) + line.Substring(indent);
//untab the lines back to the start
var minimumIndent = lines.Where(x => !string.IsNullOrWhiteSpace(x)).Min(x => x.TakeWhile(char.IsWhiteSpace).Count());
// untab
lines = lines.Select(x => new string(x.Skip(minimumIndent).ToArray()));
// replace "//#" with the line number
lines = lines.Select((s, i) => s.Replace("//#", "// line " + (i + 1)));
return string.Join(Environment.NewLine, lines);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment