From 1a6a940db0a2da68fc24d247a7d43cf9d8728793 Mon Sep 17 00:00:00 2001 From: Rich Date: Tue, 25 May 2010 19:05:01 +0000 Subject: [PATCH] Outlines the RTF version of the table --- .../OutlineRTFTable.cs | 303 ++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 PROMS/Volian.Controls.Library/OutlineRTFTable.cs diff --git a/PROMS/Volian.Controls.Library/OutlineRTFTable.cs b/PROMS/Volian.Controls.Library/OutlineRTFTable.cs new file mode 100644 index 00000000..d89ca607 --- /dev/null +++ b/PROMS/Volian.Controls.Library/OutlineRTFTable.cs @@ -0,0 +1,303 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; + +namespace Volian.Controls.Library +{ + public class OutlineRTFTable + { + public OutlineRTFTable(string rtf, bool withBorder) + { + Rtf = rtf; + WithBorder = withBorder; + } + private string _Rtf; + public string Rtf + { + get { return _Rtf; } + set { _Rtf = value; } + } + private bool _WithBorder; + public bool WithBorder + { + get { return _WithBorder; } + set { _WithBorder = value; } + } + private RtfLines _Lines; + public RtfLines Lines + { + get + { + if (_Lines == null) + _Lines = new RtfLines(Rtf); + return _Lines; + } + } + public void OutlineTable() + { + int maxWidth = Lines.MaximumWidth;// Determine maximum width + // spaces here if not an outlined table: + Lines.Pad(maxWidth, WithBorder ? @"\u9474?" : " "); // Pad the lines to the appropriate width + Lines.Insert(0, new RtfLine(maxWidth, WithBorder ? @"\u9484?" : " ", WithBorder ? @"\u9472?" : " ", WithBorder ? @"\u9488?" : " ")); // Insert top line + Lines.Add(new RtfLine(maxWidth, WithBorder ? @"\u9492?" : " ", WithBorder ? @"\u9472?" : " ", WithBorder ? @"\u9496?" : " ")); // Insert bottom line + Lines.ReplaceLines(WithBorder); + } + public override string ToString() + { + return Lines.ToString(); + } + } + public class RtfLines : List + { + public static Regex _RegReplaceLine = new Regex(@"\\line((\\[^ \[\]\\\(\)]*) )"); + public RtfLines(string text) + { + // replace RTF \line with crlf + string txt = _RegReplaceLine.Replace(text, "$1\r\n"); + // split text into lines + string[] breaks = { "\r\n" }; + string[] lines = txt.Split(breaks, StringSplitOptions.None); + string lastLine = lines[lines.Length - 1]; + foreach (string line in lines) + Add(new RtfLine(line)); + } + public int MaximumWidth + { + get + { + int retval = 0; + foreach (RtfLine myLine in this) + if (myLine.MaximumWidth > retval) retval = myLine.MaximumWidth; + return retval; + } + } + public void Pad(int maxWidth, string edge) + { + foreach (RtfLine myLine in this) + myLine.Pad(maxWidth, edge); + + } + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + string sep = ""; + foreach (RtfLine myLine in this) + { + sb.Append(sep + myLine.ToString()); + sep = "\r\n"; + } + return sb.ToString(); + } + private static Regex _RegRightCheck = new Regex(@"-|\\u9472?|\\u8209\?"); + private static Regex _RegAboveCheck = new Regex(@"\||\\u9474\?|\\u9492\?|\\u9516\?|\\u9532\?|\\u9500\?|\\u9484\?|\\u9524\?|\\u9488\?|\\u9508\?"); + private static Regex _RegLeftCheck = new Regex(@"-|\\u9472\?|\\u9508\?|\\u9516\?|\\u9500\?|\\u9532\?|\\u9484\?|\\u9488\?|\\u9492\?|\\u8209\?"); + private static Regex _RegBelowCheck = new Regex(@"\||\\u9474\?"); + + private static Regex _RegRightCheck1 = new Regex(@"\\u9474\?"); + private static Regex _RegAboveCheck1 = new Regex(@"\\u9472\?|\\u8209\?"); + private static Regex _RegLeftCheck1 = new Regex(@"\\u9474\?"); + private static Regex _RegBelowCheck1 = new Regex(@"\\u9472\?|\\u8209\?"); + + private static Regex _RegHorizontalCheck = new Regex(@"-|\\u9472\?|\\u8209\?"); + private static Regex _RegVerticalCheck = new Regex(@"\||\\u9474\?"); + static private string[] TableCharsU = { + "\x0", // HEX"\x0", // No character + @"\u9472?", // HEX@"\u2500",// - Horizontal line - 16-bit char: '\xC4' + @"\u9474?", // HEX@"\u2502",// | Vertical line - 16-bit char: '\xB3' + @"\u9492?", // HEX@"\u2514",// L Bottom Left corner - 16-bit char: '\xC0' + @"\u9472?", // HEX@"\u2500",// - Horizontal line - 16-bit char: '\xC4' + @"\u9472?", // HEX@"\u2500",// - Horizontal line - 16-bit char: '\xC4' + @"\u9496?", // HEX@"\u2518",// Bottom Right Corner - 16-bit char: '\xD9' + @"\u9524?", // HEX@"\u2534",// Bottom Tee - 16-bit char: '\xC1' + @"\u9474?", // HEX@"\u2502",// | Vertical Bar - 16-bit char: '\xB3' + @"\u9484?", // HEX@"\u250c",// Upper Left corner - 16-bit char: '\xDA' + @"\u9474?", // HEX@"\u2502",// | Vertical Bar - 16-bit char: '\xB3' + @"\u9500?", // HEX@"\u251c",// Left Tee - 16-bit char: '\xC3' + @"\u9488?", // HEX@"\u2510",// Upper Right corner - 16-bit char: '\xBF' + @"\u9516?", // HEX@"\u252c",// T Top Tee - 16-bit char: '\xC2' + @"\u9508?", // HEX@"\u2524",// Right Tee - 16-bit char: '\xB4' + @"\u9532?", // HEX@"\u253c" // + Plus - 16-bit char: '\xC5' + }; + internal void ReplaceLines(bool withBorder) + { + int maxWidth = this[0].Count; + for (int row = 1; row < Count - 1; row++) + { + RtfLine lineAbove = this[row - 1]; + RtfLine line = this[row]; + RtfLine lineBelow = this[row + 1]; + for (int col = 1; col < maxWidth - 1; col++) + { + RtfPiece curPiece = line[col]; + string current = curPiece.Text; + bool horizontal = _RegHorizontalCheck.IsMatch(current); // Horizontal + bool vertical = _RegVerticalCheck.IsMatch(current); // Vertical + if (horizontal || vertical) + { + int index = _RegRightCheck.IsMatch(line[col + 1].Text) || + (horizontal && _RegRightCheck1.IsMatch(line[col + 1].Text)) ? 1 : 0; // Right + index += _RegAboveCheck.IsMatch(lineAbove[col].Text) || + (vertical && _RegAboveCheck1.IsMatch(lineAbove[col].Text)) ? 2 : 0; // Above + index += _RegLeftCheck.IsMatch(line[col - 1].Text) || + (horizontal && _RegLeftCheck1.IsMatch(line[col - 1].Text)) ? 4 : 0; // Left + index += _RegBelowCheck.IsMatch(lineBelow[col].Text) || + (vertical && _RegBelowCheck1.IsMatch(lineBelow[col].Text)) ? 8 : 0; // Below + if (index > 0) + { + curPiece.Text = TableCharsU[index]; + // this connects the lines to the border, so only do it if there is a border + if (withBorder) + { + if (vertical && row == 1) lineAbove[col].Text = TableCharsU[13]; // Upper Tee + if (vertical && row == Count - 2) lineBelow[col].Text = TableCharsU[7]; // Lower Tee + if (horizontal && col == 1) line[col - 1].Text = TableCharsU[11];// Left Tee + if (horizontal && col == maxWidth - 2) line[col + 1].Text = TableCharsU[14];// Right Tee + } + } + } + } + } + } + private void ListItems(string loc, string str) + { + StringBuilder sb = new StringBuilder(string.Format("{0} = @\"", loc)); + string sep = ""; + foreach (char c in str) + { + if (c < 127) + sb.Append(sep + c.ToString()); + else + sb.Append(sep + string.Format("\\u{0}?", (int)c)); + sep = "|"; + } + Console.WriteLine(sb.ToString()); + } + } + public class RtfLine : List + { + private static Regex _RegRtfText = new Regex(@"((\\[^'u ]*)+( |$))?(|\\'[0-9a-fA-F]{2}|\\u[0-9]*\?|[^\\]{1}|$|)"); + public RtfLine(string text) + { + MatchCollection matches = _RegRtfText.Matches(text); + int nextIndex = 0; + foreach (Match match in matches) + { + if (nextIndex != match.Index) // This should never happen + { + throw new Exception(string.Format("\"RtfPiece Missing Content\",{0},{1},\"{2}\",\"{3}\",\"{4}\"", nextIndex, match.Index, text.Substring(nextIndex, match.Index - nextIndex), match.Groups[2].Value, match.Groups[4].Value)); + //Console.WriteLine("\"RtfPiece Missing Content\",{0},{1},\"{2}\",\"{3}\",\"{4}\"", nextIndex, match.Index, text.Substring(nextIndex, match.Index - nextIndex), match.Groups[2].Value, match.Groups[4].Value); + //Console.WriteLine(text.Substring(nextIndex)); + } + nextIndex = match.Index + match.Length; + if (match.Groups[2].ToString().Length + match.Groups[4].ToString().Length > 0) + this.Add(new RtfPiece(match.Groups[2].ToString(), match.Groups[4].ToString())); + } + } + public RtfLine(int width, string left, string fill, string right) + { + Add(new RtfPiece("", left)); + for (int i = 0; i < width; i++) this.Add(new RtfPiece("", fill)); // Pad + Add(new RtfPiece("", right)); + } + public int MaximumWidth + { + get + { + int retval = 0; + foreach (RtfPiece myPiece in this) + retval += myPiece.MaximumWidth; + return retval; + } + } + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + foreach (RtfPiece myPiece in this) + sb.Append(myPiece.ToString()); + return sb.ToString(); + } + internal void Pad(int maxWidth, string edge) + { + int pad = maxWidth - MaximumWidth; + this.Insert(0, new RtfPiece("", edge)); // Left Edge + for (int i = 0; i < pad; i++) this.Add(new RtfPiece("", " ")); // Pad + this.Add(new RtfPiece("", edge)); // Right Edge + } + public new RtfPiece this[int index] + { + get + { + int j = 0; + foreach (RtfPiece myPiece in this) + { + if (myPiece.Text != "") + { + if (j == index) return myPiece; + j++; + } + } + return null; + } + } + } + public class RtfPiece + { + private string _Rtf; + public string Rtf + { + get { return _Rtf; } + set { _Rtf = value; } + } + private string _Text = ""; + public string Text + { + get { return _Text; } + set { _Text = value; } + } + public int TextLength + { + get { return Text.Length; } + } + public int MaximumWidth + { + get { return Text == "" ? 0 : 1; } + } + private static Regex _RegStartLink = new Regex(@""); + public RtfPiece(string rtf, string text) + { + _Rtf = rtf; + if (_RegStartLink.IsMatch(text) || _RegEndLink.IsMatch(text)) + _Rtf += (rtf == "" ? "" : " ") + text; + else + { + _Rtf += rtf == "" ? "" : " "; + _Text = text; + } + } + public override string ToString() + { + return _Rtf + _Text; + //string retval = _RegUnicode.Replace(_Text, new MatchEvaluator(RtfUnicodeCharacter)); + //retval = _RegHex.Replace(retval, new MatchEvaluator(RtfHexCharacter)); + //return retval; + } + //private static Regex _RegUnicode = new Regex(@"\\u([0-9ABCDEF]*)\?"); + //internal static string RtfUnicodeCharacter(Match myMatch) + //{ + // string hexStr = myMatch.Groups[1].ToString(); + // int i = int.Parse(hexStr); + // Char schar = Convert.ToChar(i); + // return schar.ToString(); + //} + //private static Regex _RegHex = new Regex(@"\\'([0-9A-Fa-f]{2})"); + //internal static string RtfHexCharacter(Match myMatch) + //{ + // string hexStr = myMatch.Groups[1].ToString(); + // int i = int.Parse(hexStr, System.Globalization.NumberStyles.HexNumber); + // Char schar = Convert.ToChar(i); + // return schar.ToString(); + //} + } +}