Created
June 26, 2010 15:07
-
-
Save robfe/454117 to your computer and use it in GitHub Desktop.
Extract #regions into individual txt files for INCLUDETEXT in word...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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