639 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			639 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Text;
 | |
| //using System.Windows.Forms;
 | |
| using System.Text.RegularExpressions;
 | |
| using System.Drawing;
 | |
| 
 | |
| namespace Volian.Svg.Library
 | |
| {
 | |
| 	public class DisplayText
 | |
| 	{
 | |
| 		#region Properties
 | |
| 		// list of 'pieces of text' for this item.  Pieces include symbols, ros, 
 | |
| 		// transitions & plain text.
 | |
| 		private List<displayTextElement> _DisplayTextElementList;
 | |
| 		public List<displayTextElement> DisplayTextElementList
 | |
| 		{
 | |
| 			get { return _DisplayTextElementList; }
 | |
| 			set { _DisplayTextElementList = value; }
 | |
| 		}
 | |
| 		// dictionary for the font table for this item.  Note that this may
 | |
| 		// go away (it is not really used).
 | |
| 		private Dictionary<int, string> _dicRtfFontTable;
 | |
| 		public Dictionary<int, string> dicRtfFontTable
 | |
| 		{
 | |
| 			get { return _dicRtfFontTable; }
 | |
| 			set { _dicRtfFontTable = value; }
 | |
| 		}
 | |
| 		public string OriginalText;		// compare for save to see if change.
 | |
| 		#endregion
 | |
| 		#region Constructors
 | |
| 		private Font TextFont;
 | |
| 
 | |
| 		/// <summary>
 | |
| 		///     DisplayText constructor:
 | |
| 		///			Creates a DisplayText object that converts the database text into a list of 
 | |
| 		///				displayTextElement elements.
 | |
| 		///			Arguments are:
 | |
| 		///				ItemInfo itemInfo - the item whose text will be resolved
 | |
| 		///				E_EditPrintMode ep_mode - edit or print.
 | |
| 		///				E_ViewMode vw_mode - view or edit.
 | |
| 		/// </summary>
 | |
| 		public DisplayText(string text)
 | |
| 		{
 | |
| 			DisplayTextElementList = new List<displayTextElement>();
 | |
| 			OriginalText = text;
 | |
| 			TextFont = new Font("Prestige Elite Tall",12);
 | |
| 			//TextFont = GetItemFont();
 | |
| 
 | |
| 			// if in print mode or view mode, do replace words.  Only if in edit mode are replace
 | |
| 			// words left as is.
 | |
| 			//_MyFormat = itemInfo.ActiveFormat;
 | |
| 			//if (epMode == E_EditPrintMode.Print || vwMode == E_ViewMode.View) text = DoReplaceWords(text);
 | |
| 
 | |
| 			// as a precaution, convert any \~ to \u160?. This is for Hard spaces.. see the commentary in the
 | |
| 			// save portion of this code for an explanation.
 | |
| 			text = text.Replace(@"\~", @"\u160?");
 | |
| 
 | |
| 			// replace the dash/hyphen or whatever you want to call it, with a hard hyphen.  The 16-bit program
 | |
| 			// treated the dash/hyphen as such.  Translate back on any data saves.
 | |
| 			text = text.Replace(@"-", @"\u8209?");
 | |
| 
 | |
| 			// displayTextElement List items are created for anything that is handled differently in RTB, i.e.
 | |
| 			// symbols, ros, trans, text.
 | |
| 			int startIndex = 0;
 | |
| 			int index = -1;
 | |
| 			while ((index = FindTokenChar(text, startIndex)) > -1)
 | |
| 			{
 | |
| 				// Do any 'plain' text that preceeds the token.
 | |
| 				if (index > startIndex) DoTextElement(text, startIndex, index);
 | |
| 
 | |
| 				// Now do any other types
 | |
| 				if (text[index] == '\x15')
 | |
| 					index = DoRO(text, index);
 | |
| 				else if (text[index] == '\x252C' || text[index] == '\x2566')
 | |
| 					index = DoTran(text, index);
 | |
| 				else
 | |
| 					index = DoSymbol(text, startIndex, index);
 | |
| 				startIndex = index; // +1;
 | |
| 				if (startIndex >= text.Length) break;
 | |
| 			}
 | |
| 			// Add any remaining text.
 | |
| 			if (startIndex < text.Length) DoTextElement(text, startIndex, index);
 | |
| 		}
 | |
| 		#endregion
 | |
| 		#region SaveData
 | |
| 		//public bool Save(string rtf)
 | |
| 		//{
 | |
| 		//  try
 | |
| 		//  {
 | |
| 		//    List<displayLinkElement> origList = GetLinkList(DisplayTextElementList);
 | |
| 		//    // massage string to store in DisplayTextElementList...
 | |
| 		//    RtfToDisplayTextElements(rtf);
 | |
| 		//    // take the list & convert to data in the format to save to the database.
 | |
| 		//    StringBuilder sret = new StringBuilder();
 | |
| 		//    foreach (displayTextElement vte in DisplayTextElementList)
 | |
| 		//    {
 | |
| 		//      if (vte.Type == E_TextElementType.Text || vte.Type == E_TextElementType.Symbol)
 | |
| 		//        sret.Append(vte.Text);
 | |
| 		//      else if (vte.Type == E_TextElementType.ReferencedObject)
 | |
| 		//        sret.Append(ToData_RO((displayLinkElement)vte));
 | |
| 		//      else if (vte.Type == E_TextElementType.Transition || vte.Type == E_TextElementType.TransitionRange)
 | |
| 		//        sret.Append(ToData_Trans((displayLinkElement)vte));
 | |
| 		//    }
 | |
| 		//    string modtext = sret.ToString();
 | |
| 		//    if (modtext != OriginalText)
 | |
| 		//    {
 | |
| 		//      Item itm = _MyItemInfo.Get();
 | |
| 		//      // check for different text, i.e. text from this itm doesn't match
 | |
| 		//      // original text.
 | |
| 		//      if (OriginalText != itm.MyContent.Text)
 | |
| 		//      {
 | |
| 		//        Console.WriteLine("Save Failed because text changed outside of this edit session.");
 | |
| 		//        return false;
 | |
| 		//      }
 | |
| 		//      // Compare ro/transition lists and delete or add any to the item for any ros/transitions that have been
 | |
| 		//      // added/deleted or modified.
 | |
| 		//      ProcessRoTranChanges(itm, origList);
 | |
| 		//      itm.MyContent.Text = modtext;
 | |
| 		//      itm.Save();
 | |
| 		//      OriginalText = modtext;
 | |
| 		//    }
 | |
| 		//    else
 | |
| 		//      return true;  // no text changed, but did not fail so return true.
 | |
| 		//  }
 | |
| 		//  catch (Exception ex)
 | |
| 		//  {
 | |
| 		//    Console.WriteLine("Save Failed with error: {0}", ex.Message);
 | |
| 		//    return false;
 | |
| 		//  }
 | |
| 		//  return true;
 | |
| 		//}
 | |
| 		private List<displayLinkElement> GetLinkList(List<displayTextElement> locDisplayTextElementList)
 | |
| 		{
 | |
| 			List<displayLinkElement> retList = new List<displayLinkElement>();
 | |
| 			foreach (displayTextElement vte in locDisplayTextElementList)
 | |
| 			{
 | |
| 				if (vte.Type == E_TextElementType.ReferencedObject || vte.Type == E_TextElementType.TransitionRange || vte.Type == E_TextElementType.Transition)
 | |
| 				{
 | |
| 					displayLinkElement tmp = (displayLinkElement)vte;
 | |
| 					displayLinkElement copy_vte = new displayLinkElement();
 | |
| 					copy_vte.Type = tmp.Type;
 | |
| 					copy_vte.Link = tmp.Link;
 | |
| 					copy_vte.Text = tmp.Text;
 | |
| 					retList.Add(copy_vte);
 | |
| 				}
 | |
| 			}
 | |
| 			return retList;
 | |
| 		}
 | |
| 		private void RtfToDisplayTextElements(string rtf)
 | |
| 		{
 | |
| 			// For hardspaces, the windows richtextbox does some 'quirky' things:
 | |
| 			// A unicode representation of \u160? is sent INTO the rtb.  Coming out, 
 | |
| 			// that \u160? was translated to a \~ (by the underlying windows rtb).
 | |
| 			// Note that if the \~ is sent to the rtb, it is treated as a regular space,
 | |
| 			// i.e. no longer a hardspace, and actually is converted to a regular space.
 | |
| 			// SO, on the way out, convert any \~ to \u160?
 | |
| 			string noExtraRtfStr = rtf.Replace(@"\~", @"\u160?");
 | |
| 
 | |
| 
 | |
| 			// GetFontTable returns a non-negative number font number in the
 | |
| 			// font table for the unicode font, if it is used (otherwise -1)
 | |
| 			//int unicodeFont = GetFontTable(rtb.Rtf);
 | |
| 
 | |
| 			// strip off all rtf commands...
 | |
| 			noExtraRtfStr = StripRtfCommands(noExtraRtfStr);
 | |
| 			//Console.WriteLine("StripRtf: {0}", noExtraRtfStr);
 | |
| 
 | |
| 			// Also, set back the hard dash to a regular dash...  Do this after the removal
 | |
| 			// of other rtf commands though since the \u8209 was surrounded by font commands
 | |
| 			// that, without there removal first, was also removing the dash.  Have it with 
 | |
| 			// a space & without because if it is at the end, there will be no space (leave
 | |
| 			// it to rtf processing to make it more complicated)
 | |
| 			noExtraRtfStr = noExtraRtfStr.Replace(@"\u8209? ", @"-");
 | |
| 			noExtraRtfStr = noExtraRtfStr.Replace(@"\u8209?", @"-");
 | |
| 
 | |
| 			DisplayTextElementList.Clear();
 | |
| 			int startIndex = 0;
 | |
| 			int index = -1;
 | |
| 			while ((index = FindRtfChar(noExtraRtfStr, startIndex)) > -1)
 | |
| 			{
 | |
| 				int fndindx = -1;
 | |
| 				// Do any 'plain' text that preceeds the token.
 | |
| 				if (index > startIndex)
 | |
| 					index = SaveTextElement(noExtraRtfStr, startIndex, index);
 | |
| 				if ((fndindx = noExtraRtfStr.IndexOf(@"\protect", index)) == index)
 | |
| 					index = SaveLink(noExtraRtfStr, index);
 | |
| 				else
 | |
| 					index = SaveSymbolTE(noExtraRtfStr, index);
 | |
| 				startIndex = index + 1;
 | |
| 				if (startIndex >= noExtraRtfStr.Length) break;
 | |
| 			}
 | |
| 			// Add any remaining text.
 | |
| 			if (startIndex < noExtraRtfStr.Length) DoTextElement(noExtraRtfStr, startIndex, index);
 | |
| 			//Console.WriteLine(noExtraRtfStr);
 | |
| 		}
 | |
| 		private int SaveTextElement(string data, int startIndex, int index)
 | |
| 		{
 | |
| 			displayTextElement vte = new displayTextElement();
 | |
| 			vte.Type = E_TextElementType.Text;
 | |
| 			int len = (index == -1) ? data.Length - startIndex : index - startIndex;
 | |
| 			vte.Text = data.Substring(startIndex, len);
 | |
| 			DisplayTextElementList.Add(vte);
 | |
| 			return index;
 | |
| 		}
 | |
| 		private int SaveSymbolTE(string data, int startIndex)
 | |
| 		{
 | |
| 			displayLinkElement vte = new displayLinkElement();
 | |
| 			vte.Type = E_TextElementType.Symbol;
 | |
| 			// symbols are just the unicode/rtf command, no font associated with it
 | |
| 			// by the time it gets here... A symbol can be represented by \'xy or \uxyz?
 | |
| 			// if the \'xy is used the length of the symbol number will always be two,
 | |
| 			// otherwise find the index of the '?' to find the end.
 | |
| 			int endindx = -1;
 | |
| 			if (data[startIndex + 1] == '\'') endindx = startIndex + 3;
 | |
| 			else endindx = data.IndexOf("?", startIndex);
 | |
| 			if (endindx == -1) return startIndex; // not found - error
 | |
| 			vte.Text = data.Substring(startIndex, endindx - startIndex + 1);
 | |
| 			DisplayTextElementList.Add(vte);
 | |
| 			if (endindx + 1 < data.Length && data[endindx + 1] != ' ') return endindx;
 | |
| 			return endindx + 1;	// add one to get past the space that was added after a symbol (to end the font cmd)
 | |
| 		}
 | |
| 		private int SaveLink(string data, int stIndex)
 | |
| 		{
 | |
| 			////displayLinkElement vte = new displayLinkElement();
 | |
| 			//// find the end of the link text, i.e. either the ending \v0 or \protect0.  The win32 rtf box can
 | |
| 			//// put these in either order, take the lowest index.
 | |
| 			//int startIndex = stIndex + @"\protect ".Length;
 | |
| 			//int indx_v0 = data.IndexOf(@"\v0", startIndex);
 | |
| 			//int indx_protect0 = data.IndexOf(@"\protect0", startIndex);
 | |
| 			//int indx = indx_v0 < indx_protect0 ? indx_v0 : indx_protect0;
 | |
| 			//LinkText lt = new LinkText(data.Substring(startIndex, indx - startIndex));
 | |
| 			//displayLinkElement vte = new displayLinkElement();
 | |
| 			//vte.Type = (E_TextElementType)lt.MyParsedLinkType;
 | |
| 			//vte.Text = lt.MyValue;
 | |
| 			//vte.Link = lt.MyLink;
 | |
| 			//DisplayTextElementList.Add(vte);
 | |
| 			//return (indx_v0 < indx_protect0 ? indx_protect0 + 1 : indx_v0 + 1);
 | |
| 			////if (lt.MyParsedLinkType == ParsedLinkType.ReferencedObject) return 
 | |
| 			////// first find if ReferencedObject or trans, the ReferencedObject has a #R.
 | |
| 			////int istart = data.IndexOf("#Link:", startIndex);
 | |
| 			////if (data[istart + 6] == 'R') return SaveROTE(data, startIndex);
 | |
| 			////else if (data.Substring(istart+6,11) == "TransitionR")
 | |
| 			////    return SaveTranTE(data, startIndex, E_TextElementType.TRANS_Range);
 | |
| 			////return SaveTranTE(data, startIndex,  E_TextElementType.TRANS_Single);
 | |
| 			return 0;
 | |
| 		}
 | |
| 		//private int SaveTranTE(string data, int startIndex, E_TextElementType type)
 | |
| 		//{
 | |
| 		//    displayLinkElement vte = new displayLinkElement();
 | |
| 
 | |
| 		//    vte.Type = type;
 | |
| 		//    // \protect {transition text} \v #Link:Transition(Range): 1 2 3\protect0\v0  
 | |
| 		//    //  where 1 2 3 are transition type and ids
 | |
| 		//    int indx = data.IndexOf("\\v #Link:Transition", startIndex);
 | |
| 		//    // use '9' to get past \\protect
 | |
| 		//    vte.Text = data.Substring(startIndex + 9, indx - startIndex - 9);
 | |
| 		//    // the link is the text between the #Link... and the next '\\'.
 | |
| 		//    int iend = data.IndexOf("\\", indx+1);
 | |
| 		//    int bindx = data.IndexOf("#", indx);
 | |
| 		//    vte.Link = data.Substring(bindx, iend - bindx);			 
 | |
| 		//    DisplayTextElementList.Add(vte);
 | |
| 		//    // unfortunately, the rtf box may add the \protect0 \v0 in either order
 | |
| 		//    // and with or without one or more spaces between then.  The number of text
 | |
| 		//    // characters = 11 for \protect0\v0 - find the number of spaces between them
 | |
| 		//    // if any?
 | |
| 		//    int nsp = 0;
 | |
| 		//    for (int c = iend; c < iend + 11; c++) if (data[c] == ' ') nsp++;
 | |
| 		//    return iend + 11 + nsp;
 | |
| 		//}
 | |
| 		//private int SaveROTE(string data, int startIndex)
 | |
| 		//{
 | |
| 		//    displayLinkElement vte = new displayLinkElement();
 | |
| 		//    vte.Type = E_TextElementType.ReferencedObject;
 | |
| 		//    // \protect {rovalue} \v #Link:ReferencedObject (RoUsageId) {ROID}\protect0\v0
 | |
| 		//    int indx = data.IndexOf("\\v #Link:ReferencedObject", startIndex);
 | |
| 		//    // use '9' to get past \\protect
 | |
| 		//    vte.Text = data.Substring(startIndex + 9, indx - startIndex - 9);
 | |
| 		//    // the link is the text between the #Link... and the next '\\'.
 | |
| 		//    int iend = data.IndexOf("\\", indx);
 | |
| 		//    int bindx = data.IndexOf("#", indx);
 | |
| 		//    vte.Link = data.Substring(bindx, iend - bindx);
 | |
| 		//    DisplayTextElementList.Add(vte);
 | |
| 		//    // unfortunately, the rtf box may add the \protect0 \v0 in either order
 | |
| 		//    // and with or without one or more spaces between then.  The number of text
 | |
| 		//    // characters = 11 for \protect0\v0 - find the number of spaces between them
 | |
| 		//    // if any?
 | |
| 		//    int nsp = 0;
 | |
| 		//    for (int c = iend; c < iend + 11; c++) if (data[c] == ' ') nsp++;
 | |
| 		//    return iend + 11 + nsp;
 | |
| 		//}
 | |
| 		private int FindRtfChar(string text, int startIndex)
 | |
| 		{
 | |
| 			int prindx = text.IndexOf("\\protect", startIndex);
 | |
| 			int symindx1 = text.IndexOf("\\'", startIndex);
 | |
| 			int symindx2 = text.IndexOf("\\u", startIndex);
 | |
| 			if (symindx2 > -1)
 | |
| 			{
 | |
| 				if (text[symindx2 + 2] == 'l') symindx2 = -1;	// don't process underlines
 | |
| 			}
 | |
| 			if (prindx == -1 && symindx1 == -1 && symindx2 == -1) return -1;
 | |
| 			if (prindx == -1) prindx = text.Length + 1;
 | |
| 			if (symindx1 == -1) symindx1 = text.Length + 1;
 | |
| 			if (symindx2 == -1) symindx2 = text.Length + 1;
 | |
| 
 | |
| 			// Which token has smallest number, to determine which item is next
 | |
| 			// in the string.  If it is a symbol - see if it has a font specifier
 | |
| 			// first.
 | |
| 			int symindx = symindx1 < symindx2 ? symindx1 : symindx2;
 | |
| 			int smallest = (prindx < symindx ? prindx : symindx);
 | |
| 			return smallest;
 | |
| 		}
 | |
| 		private int GetFontTable(string rtf)
 | |
| 		{
 | |
| 			dicRtfFontTable = new Dictionary<int, string>();
 | |
| 			// return unicode (symbol) font number, if it exists, to expedite finding
 | |
| 			// the font for symbols.
 | |
| 			int unicodeFont = -1;
 | |
| 			int bindx = rtf.IndexOf(@"{\fonttbl");
 | |
| 			if (bindx < -1) return -1;
 | |
| 			int eindx = rtf.IndexOf("}}", bindx);
 | |
| 			// get font table string and then do regular expressions to get font number 
 | |
| 			// with font name.
 | |
| 			string tbl = rtf.Substring(bindx + 9, eindx - bindx - 8);
 | |
| 			tbl = tbl.Replace("{", "<");
 | |
| 			tbl = tbl.Replace("}", ">");
 | |
| 			string pat = @"(?:<\\f)([0-9]+)(?:[\S]+ )([\w ]+)";
 | |
| 			StringBuilder sb = new StringBuilder();
 | |
| 			foreach (Match m in Regex.Matches(tbl, pat))
 | |
| 			{
 | |
| 				int num = Convert.ToInt32(m.Result("${1}"));
 | |
| 				string nam = m.Result("${2}");
 | |
| 				dicRtfFontTable.Add(num, nam);
 | |
| 				if ((unicodeFont == -1) && (nam == "Arial Unicode MS")) unicodeFont = num;
 | |
| 			}
 | |
| 			return unicodeFont;
 | |
| 		}
 | |
| 		public static string ReplaceRTFClause(Match m)
 | |
| 		{
 | |
| 			switch (m.Value[1])
 | |
| 			{
 | |
| 				case 'u':
 | |
| 					if (Regex.IsMatch(m.Value, @"\\u[0-9]+"))
 | |
| 						return m.Value; // Special Charcaters
 | |
| 					if (Regex.IsMatch(m.Value, @"\\ulnone"))
 | |
| 						return m.Value;
 | |
| 					if (Regex.IsMatch(m.Value, @"\\ul.*"))
 | |
| 						return m.Value; // Underline
 | |
| 					if (Regex.IsMatch(m.Value, @"^\\up[0-9] ?$"))
 | |
| 						return m.Value; // shift up (superscript)
 | |
| 					break;
 | |
| 				case 'd':
 | |
| 					if (Regex.IsMatch(m.Value, @"^\\dn[0-9] ?$"))
 | |
| 						return m.Value; // shift down (subscript)
 | |
| 					break;
 | |
| 				case '\'': // Special Character
 | |
| 					return m.Value;
 | |
| 				case 'b': // Bold
 | |
| 					return m.Value;
 | |
| 				case 'i': // Italics
 | |
| 					return m.Value;
 | |
| 				case 'v': // save link hidden info
 | |
| 					if (m.Value == @"\v") return m.Value;	// part of link
 | |
| 					if (Regex.IsMatch(m.Value, @"\\v0"))
 | |
| 						return m.Value; // hidden info off
 | |
| 					break;
 | |
| 				case 'p':
 | |
| 					if (m.Value == @"\par") return "\r\n";
 | |
| 					if (m.Value == @"\protect")
 | |
| 						return m.Value;
 | |
| 					if (m.Value == @"\protect0")
 | |
| 						return m.Value;
 | |
| 					break;
 | |
| 			}
 | |
| 			return "";//Strip All
 | |
| 		}
 | |
| 		public static string StripRtfCommands(string rtf)
 | |
| 		{
 | |
| 			string retval = Regex.Replace(rtf, @"[\r\n]", "", RegexOptions.Singleline); // Strip Carriage Returns and Newlines
 | |
| 			retval = Regex.Replace(retval, @"^\{(.*)\}$", "$1", RegexOptions.Singleline); // Strip Opening and Closing Braces
 | |
| 			retval = Regex.Replace(retval, @"\{[^{]*?\}", "", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces
 | |
| 			retval = Regex.Replace(retval, @"\{[^{]*?\}", "", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces
 | |
| 			retval = Regex.Replace(retval, @"\\[^ \\?]+", new MatchEvaluator(ReplaceRTFClause));  // take backslash xyz and evaluates them
 | |
| 			// remove a space if there is one as the first character..
 | |
| 			if (retval[0] == ' ') retval = retval.Remove(0, 1);
 | |
| 			// remove \r\n at end of string - this was added with the \par at the end of string by the rtf box
 | |
| 			if (retval.Substring(retval.Length - 2, 2) == "\r\n") retval = retval.Remove(retval.Length - 2, 2);
 | |
| 
 | |
| 			return retval;
 | |
| 		}
 | |
| 		private string ToData_RO(displayLinkElement vte)
 | |
| 		{
 | |
| 			// get past the #Link:ReferencedObject part of the link.
 | |
| 			return String.Format("\x15ReferencedObjectv RO\\v0 {0}\\v #{1}\\v0", vte.Text, vte.Link.Substring(23, vte.Link.Length - 23));
 | |
| 		}
 | |
| 		private string ToData_Trans(displayLinkElement vte)
 | |
| 		{
 | |
| 			char trchar = vte.Type == E_TextElementType.Transition ? '\x252C' : '\x2566';
 | |
| 			// depending on type, get past the #Link:Transition: or #Link:TransitionRange: part
 | |
| 			// of text.
 | |
| 			int indx = vte.Type == E_TextElementType.Transition ? 18 : 23;
 | |
| 			return String.Format("{0}\\v TRAN\\v0 {1}\\v {2}\\v0", trchar, vte.Text, vte.Link.Substring(indx, vte.Link.Length - indx));
 | |
| 		}
 | |
| 		#endregion
 | |
| 		//#region StyleData
 | |
| 		//private VE_Font GetItemFont()
 | |
| 		//{
 | |
| 		//  VE_Font font = null;
 | |
| 		//  FormatInfo format = _MyItemInfo.ActiveFormat;
 | |
| 		//  int type = (int)_MyItemInfo.MyContent.Type;
 | |
| 		//  switch (type / 10000)
 | |
| 		//  {
 | |
| 		//    case 0:	// procedure
 | |
| 		//      font = format.PlantFormat.FormatData.Font;
 | |
| 		//      break;
 | |
| 		//    case 1: // section
 | |
| 		//      font = format.PlantFormat.FormatData.SectData.SectionHeader.Font;
 | |
| 		//      break;
 | |
| 		//    case 2: // step types
 | |
| 		//      int typindx = type - 20000;  // what to do for other types rather than steps
 | |
| 		//      font = format.PlantFormat.FormatData.StepDataList[typindx].Font;
 | |
| 		//      break;
 | |
| 		//  }
 | |
| 		//  TextFont = font;
 | |
| 		//  return font;
 | |
| 		//}
 | |
| 		//#endregion
 | |
| 		#region DoListElements
 | |
| 		private int FindTokenChar(string txt, int startIndex)
 | |
| 		{
 | |
| 			// tokens are ro, transitions and possible symbol
 | |
| 			char[] tok = { '\x15', '\x252C', '\x2566', '\\' };
 | |
| 			bool done = false;
 | |
| 			// If there is only an rtf token from the indexed position on, don't return the
 | |
| 			// IndexOfAny index value, because it will by one character past the '\' and throw
 | |
| 			// of the return value of where in the string the text should be saved.  For example
 | |
| 			// for the string '\b text \v somevalue \v0\b0', the first time through the while
 | |
| 			// loop has the index at the '\b' char of the b0.  
 | |
| 			//int savstartIndex = startIndex;
 | |
| 			while (!done)
 | |
| 			{
 | |
| 				int indx = txt.IndexOfAny(tok, startIndex);
 | |
| 				if (indx < 0) return indx;
 | |
| 				if (txt[indx] != '\\') return indx;
 | |
| 				// see if symbol (but not underline) or another rtf command: has a 'u' 
 | |
| 				// followed by a non-underline or single quote, and if so, return it.  
 | |
| 				// Otherwise, get next index, must have been a slash or other rtf command.
 | |
| 				if (((txt[indx + 1] == 'u' && txt[indx + 2] != 'l')) || (txt[indx + 1] == '\'')) return indx;
 | |
| 				startIndex = indx + 1;
 | |
| 			}
 | |
| 			return -1;
 | |
| 		}
 | |
| 		private int DoTextElement(string text, int startIndex, int index)
 | |
| 		{
 | |
| 			displayTextElement vte = new displayTextElement();
 | |
| 			vte.Type = E_TextElementType.Text;
 | |
| 			int len = (index == -1) ? text.Length - startIndex : index - startIndex;
 | |
| 			vte.Text = text.Substring(startIndex, len);
 | |
| 			DisplayTextElementList.Add(vte);
 | |
| 			return index + 1;
 | |
| 		}
 | |
| 		private string CreateLink(E_TextElementType type, string linktxt)
 | |
| 		{
 | |
| 			string retlink = "";
 | |
| 			if (type == E_TextElementType.ReferencedObject)
 | |
| 				retlink = "#Link:ReferencedObject:" + linktxt;
 | |
| 			else if (type == E_TextElementType.Transition)
 | |
| 				retlink = "#Link:Transition:" + linktxt;
 | |
| 			else
 | |
| 				retlink = "#Link:TransitionRange:" + linktxt;
 | |
| 
 | |
| 			return retlink;
 | |
| 		}
 | |
| 		private int DoRO(string text, int index)
 | |
| 		{
 | |
| 			displayLinkElement vte = new displayLinkElement();
 | |
| 			vte.Type = E_TextElementType.ReferencedObject;
 | |
| 			int iend = text.IndexOf(@"\v", index);
 | |
| 
 | |
| 			vte.Text = text.Substring(index + 1, iend - index - 1);
 | |
| 			int istart = text.IndexOf("#", index);
 | |
| 			iend = text.IndexOf(@"\v0", istart);
 | |
| 			vte.Link = text.Substring(istart, iend - istart);
 | |
| 			DisplayTextElementList.Add(vte);
 | |
| 			return iend + 3;
 | |
| 		}
 | |
| 		//private string FixTransition(string link, string text)
 | |
| 		//{
 | |
| 		//  int transitionID = Convert.ToInt32(link.Split(" ".ToCharArray())[1]);
 | |
| 		//  // Find the transition
 | |
| 		//  foreach (TransitionInfo ti in _MyItemInfo.MyContent.ContentTransitions)
 | |
| 		//  {
 | |
| 		//    if (ti.TransitionID == transitionID)
 | |
| 		//    {
 | |
| 		//      //string path = ti.PathTo.Replace(" Section PROCEDURE STEPS ", ", ");
 | |
| 		//      //path = path.Replace(" Section PROCEDURE STEPS", "");
 | |
| 		//      string path = ti.ResolvePathTo(_MyFormat, _MyItemInfo, ItemInfo.Get(ti.ToID), ti.RangeID == 0 ? null : ItemInfo.Get(ti.RangeID));
 | |
| 		//      return path;
 | |
| 		//    }
 | |
| 		//  }
 | |
| 		//  return text;
 | |
| 		//}
 | |
| 		private int DoTran(string text, int index)
 | |
| 		{
 | |
| 			//displayLinkElement vte = new displayLinkElement();
 | |
| 			//if (text[index] == '\x252C') vte.Type = E_TextElementType.Transition;
 | |
| 			//else vte.Type = E_TextElementType.TransitionRange;		// '\x2566'\
 | |
| 			//int iend = text.IndexOf(@"\v", index);
 | |
| 			//vte.Text = text.Substring(index + 1, iend - index - 1);
 | |
| 			//int istart = text.IndexOf("#", index);
 | |
| 			//iend = text.IndexOf(@"\v0", istart);
 | |
| 			//vte.Link = text.Substring(istart, iend - istart);
 | |
| 			//vte.Text = FixTransition(vte.Link, vte.Text);  // TODO: Transition text resolution?
 | |
| 			//DisplayTextElementList.Add(vte);
 | |
| 			//return iend + 3;
 | |
| 			return 0;
 | |
| 		}
 | |
| 		private int DoSymbol(string text, int startIndex, int index)
 | |
| 		{
 | |
| 			displayTextElement vte = new displayTextElement();
 | |
| 			vte.Type = E_TextElementType.Symbol;
 | |
| 			// symbols are the unicode/rtf command. A symbol can be represented by \'xy or 
 | |
| 			// in the text from the database \uxyz?. If the \'xy is used the length of the 
 | |
| 			// symbol number will always be two, otherwise find the index of the '?' to 
 | |
| 			// find the end.
 | |
| 			int endindx = -1;
 | |
| 			if (text[index + 1] == '\'') endindx = index + 3;
 | |
| 			else endindx = text.IndexOf("?", index);
 | |
| 			vte.Text = text.Substring(index, endindx - index + 1);
 | |
| 			DisplayTextElementList.Add(vte);
 | |
| 			// return the position just past the symbol.
 | |
| 			return endindx + 1;
 | |
| 		}
 | |
| 		#endregion
 | |
| 		#region ReplaceWords
 | |
| 		//private ReplaceStr _rs;
 | |
| 		//private string ReplaceIt(Match m)
 | |
| 		//{
 | |
| 		//  string s = m.ToString();
 | |
| 		//  string t = s.Replace(_rs.ReplaceWord, _rs.ReplaceWith);
 | |
| 		//  return m.ToString().Replace(_rs.ReplaceWord, _rs.ReplaceWith);
 | |
| 		//}
 | |
| 		//private string DoReplaceWords(string Text)
 | |
| 		//{
 | |
| 		//  ReplaceStrList rsl = _MyFormat.PlantFormat.FormatData.SectData.ReplaceStrList;
 | |
| 		//  foreach (ReplaceStr rs in rsl)
 | |
| 		//  {
 | |
| 		//    if (_MyItemInfo.MyContent.Type < 20000) return Text;   // for now only replace in steps.
 | |
| 		//    bool replaceit = false;
 | |
| 
 | |
| 		//    // note that the order of this check is important.  Check in this order...
 | |
| 		//    // background here
 | |
| 		//    if (_MyItemInfo.IsHigh && (rs.Flag & E_ReplaceFlags.High) > 0) replaceit = true;
 | |
| 		//    else if ((_MyItemInfo.IsTable || _MyItemInfo.IsFigure) && (rs.Flag & E_ReplaceFlags.Table) > 0) replaceit = true;
 | |
| 		//    else if (_MyItemInfo.IsInRNO && (rs.Flag & E_ReplaceFlags.RNO) > 0) replaceit = true;
 | |
| 		//    else if (_MyItemInfo.IsCaution && (rs.Flag & E_ReplaceFlags.Caution) > 0) replaceit = true;
 | |
| 		//    else if (_MyItemInfo.IsNote && (rs.Flag & E_ReplaceFlags.Note) > 0) replaceit = true;
 | |
| 		//    else if (_MyItemInfo.IsInFirstLevelSubStep && (rs.Flag & E_ReplaceFlags.Substep) > 0) replaceit = true;
 | |
| 		//    else if (_MyItemInfo.IsAccPages & (rs.Flag & E_ReplaceFlags.Attach) > 0) replaceit = true;
 | |
| 
 | |
| 		//    if (replaceit)
 | |
| 		//    {
 | |
| 		//      // CASEINSENS: Do ReplaceWords for all words that match, regardless of case, and replace 
 | |
| 		//      // with the ReplaceWith string as is
 | |
| 		//      if ((rs.Flag & E_ReplaceFlags.CaseInsens) > 0)
 | |
| 		//      {
 | |
| 		//        string res = "";
 | |
| 		//        string fortest = Text.ToUpper();
 | |
| 		//        string pat = @"(?<=\W|^)" + rs.ReplaceWord.ToUpper() + @"(?=\W|$)";
 | |
| 		//        int cpindx = 0;
 | |
| 		//        foreach (Match m in Regex.Matches(fortest, pat))
 | |
| 		//        {
 | |
| 		//          res += Text.Substring(cpindx, m.Index - cpindx);
 | |
| 		//          cpindx += (m.Index - cpindx);
 | |
| 		//          res += rs.ReplaceWith;
 | |
| 		//          cpindx += rs.ReplaceWord.Length;
 | |
| 		//        }
 | |
| 		//        if (cpindx < Text.Length) res += Text.Substring(cpindx, Text.Length - cpindx);
 | |
| 		//        Text = res;
 | |
| 		//      }
 | |
| 		//      // CASEINSENSALL: Do ReplaceWords for all words that match the ReplaceWord, regardless of case
 | |
| 		//      else if ((rs.Flag & E_ReplaceFlags.CaseInsensAll) > 0)
 | |
| 		//      {
 | |
| 		//        // not in hlp
 | |
| 		//      }
 | |
| 		//      // CASEINSENSFIRST:	Do ReplaceWords for all words that exactly match the ReplaceWord,  
 | |
| 		//      // except the case where the first character may be different
 | |
| 		//      else if ((rs.Flag & E_ReplaceFlags.CaseInsensFirst) > 0)
 | |
| 		//      {
 | |
| 		//        // not in hlp
 | |
| 		//      }
 | |
| 		//      else
 | |
| 		//      {
 | |
| 		//        string pat = @"(?<=\W|^)" + rs.ReplaceWord + @"(?=\W|$)";
 | |
| 		//        Text = Regex.Replace(Text, pat, rs.ReplaceWith);
 | |
| 		//      }
 | |
| 
 | |
| 		//    }
 | |
| 		//  }
 | |
| 		//  return Text;
 | |
| 		//}
 | |
| 		#endregion
 | |
| 	}
 | |
| 	#region displayTextElementClass
 | |
| 	public enum E_TextElementType : uint
 | |
| 	{
 | |
| 		Text = 0,
 | |
| 		Transition = 1,
 | |
| 		TransitionRange = 2,
 | |
| 		ReferencedObject = 3,
 | |
| 		Symbol = 4
 | |
| 	};
 | |
| 	public class displayTextElement
 | |
| 	{
 | |
| 		private E_TextElementType _Type;
 | |
| 		public E_TextElementType Type
 | |
| 		{
 | |
| 			get { return _Type; }
 | |
| 			set { _Type = value; }
 | |
| 		}
 | |
| 		private string _Text;
 | |
| 		public string Text
 | |
| 		{
 | |
| 			get { return _Text; }
 | |
| 			set { _Text = value; }
 | |
| 		}
 | |
| 	}
 | |
| 	public class displayLinkElement : displayTextElement
 | |
| 	{
 | |
| 		private string _Link;
 | |
| 		public string Link
 | |
| 		{
 | |
| 			get { return _Link; }
 | |
| 			set { _Link = value; }
 | |
| 		}
 | |
| 	}
 | |
| 	#endregion
 | |
| 
 | |
| } |