protected LinkedList <Token> buildTokenList()
        {
            int   count;
            Token token;
            LinkedList <Token>     tokList = new LinkedList <Token>();
            LinkedListNode <Token> node;
            List <DisjointRange>   dranges = new List <DisjointRange>();

            #region Build head[] and tail[] from char format range for later use.
            // --------------------------------------------------
            // Transform possibly overlapped character format ranges into
            // disjoint ranges.
            // --------------------------------------------------
            for (int i = 0; i < _charFormats.Count; i++)
            {
                RtfCharFormat fmt   = _charFormats[i];
                DisjointRange range = null;
                if (fmt.Begin == -1 && fmt.End == -1)
                {
                    range        = new DisjointRange();
                    range.head   = 0;
                    range.tail   = _text.Length - 1;
                    range.format = fmt;
                }
                else if (fmt.Begin <= fmt.End)
                {
                    range        = new DisjointRange();
                    range.head   = fmt.Begin;
                    range.tail   = fmt.End;
                    range.format = fmt;
                }
                else
                {
                    continue;
                }
                if (range.tail >= _text.Length)
                {
                    range.tail = _text.Length - 1;
                    if (range.head > range.tail)
                    {
                        continue;
                    }
                }
                // make the ranges disjoint from each other.
                List <DisjointRange> delList       = new List <DisjointRange>();
                List <DisjointRange> addList       = new List <DisjointRange>();
                List <DisjointRange> addAnchorList = new List <DisjointRange>();
                for (int j = 0; j < dranges.Count; j++)
                {
                    DisjointRange r = dranges[j];
                    if (range.head <= r.head && range.tail >= r.tail)
                    {
                        // former range is totally covered by the later
                        //       |--------| r
                        //   |-----------------| range
                        delList.Add(r);
                    }
                    else if (range.head <= r.head && range.tail >= r.head && range.tail < r.tail)
                    {
                        // former range is partially covered
                        //          |------------------| r
                        //     |-----------------| range
                        r.head = range.tail + 1;
                    }
                    else if (range.head > r.head && range.head <= r.tail && range.tail >= r.tail)
                    {
                        // former range is partially covered
                        //     |------------------| r
                        //          |-----------------| range
                        r.tail = range.head - 1;
                    }
                    else if (range.head > r.head && range.tail < r.tail)
                    {
                        // later range is totally covered by the former
                        //   |----------------------| r
                        //        |---------| range
                        DisjointRange newRange = new DisjointRange();
                        newRange.head   = range.tail + 1;
                        newRange.tail   = r.tail;
                        newRange.format = r.format;
                        r.tail          = range.head - 1;
                        addList.Add(newRange);
                        addAnchorList.Add(r);
                    }
                }
                dranges.Add(range);
                for (int j = 0; j < delList.Count; j++)
                {
                    dranges.Remove(delList[j]);
                }
                for (int j = 0; j < addList.Count; j++)
                {
                    int index = dranges.IndexOf(addAnchorList[j]);
                    if (index < 0)
                    {
                        continue;
                    }
                    dranges.Insert(index, addList[j]);
                }
            }
            #endregion
            token           = new Token();
            token.text      = _text.ToString();
            token.isControl = false;
            tokList.AddLast(token);
            #region Build token list from head[] and tail[].
            // --------------------------------------------------
            // Build token list from head[] and tail[].
            // --------------------------------------------------
            for (int i = 0; i < dranges.Count; i++)
            {
                DisjointRange r = dranges[i];
                count = 0;
                // process head[i]
                if (r.head == 0)
                {
                    Token newTok = new Token();
                    newTok.isControl = true;
                    newTok.text      = r.format.renderHead();
                    tokList.AddFirst(newTok);
                }
                else
                {
                    node = tokList.First;
                    while (node != null)
                    {
                        Token tok = node.Value;

                        if (!tok.isControl)
                        {
                            count += tok.text.Length;
                            if (count == r.head)
                            {
                                Token newTok = new Token();
                                newTok.isControl = true;
                                newTok.text      = r.format.renderHead();
                                while (node.Next != null && node.Next.Value.isControl)
                                {
                                    node = node.Next;
                                }
                                tokList.AddAfter(node, newTok);
                                break;
                            }
                            else if (count > r.head)
                            {
                                LinkedListNode <Token> newNode;
                                Token newTok1 = new Token();
                                newTok1.isControl = false;
                                newTok1.text      = tok.text.Substring(0, tok.text.Length - (count - r.head));
                                newNode           = tokList.AddAfter(node, newTok1);
                                Token newTok2 = new Token();
                                newTok2.isControl = true;
                                newTok2.text      = r.format.renderHead();
                                newNode           = tokList.AddAfter(newNode, newTok2);
                                Token newTok3 = new Token();
                                newTok3.isControl = false;
                                newTok3.text      = tok.text.Substring(tok.text.Length - (count - r.head));
                                newNode           = tokList.AddAfter(newNode, newTok3);
                                tokList.Remove(node);
                                break;
                            }
                        }
                        node = node.Next;
                    }
                }
                // process tail[i]
                count = 0;
                node  = tokList.First;
                while (node != null)
                {
                    Token tok = node.Value;

                    if (!tok.isControl)
                    {
                        count += tok.text.Length;
                        if (count - 1 == r.tail)
                        {
                            Token newTok = new Token();
                            newTok.isControl = true;
                            newTok.text      = r.format.renderTail();
                            tokList.AddAfter(node, newTok);
                            break;
                        }
                        else if (count - 1 > r.tail)
                        {
                            LinkedListNode <Token> newNode;
                            Token newTok1 = new Token();
                            newTok1.isControl = false;
                            newTok1.text      = tok.text.Substring(0, tok.text.Length - (count - r.tail) + 1);
                            newNode           = tokList.AddAfter(node, newTok1);
                            Token newTok2 = new Token();
                            newTok2.isControl = true;
                            newTok2.text      = r.format.renderTail();
                            newNode           = tokList.AddAfter(newNode, newTok2);
                            Token newTok3 = new Token();
                            newTok3.isControl = false;
                            newTok3.text      = tok.text.Substring(tok.text.Length - (count - r.tail) + 1);
                            newNode           = tokList.AddAfter(newNode, newTok3);
                            tokList.Remove(node);
                            break;
                        }
                    }
                    node = node.Next;
                }
            } // end for each char format
            #endregion
            #region Insert footnote into token list.
            // --------------------------------------------------
            // Insert footnote into token list.
            // --------------------------------------------------
            for (int i = 0; i < _footnotes.Count; i++)
            {
                int pos = _footnotes[i].Position;
                if (pos >= _text.Length)
                {
                    continue;
                }

                count = 0;
                node  = tokList.First;
                while (node != null)
                {
                    Token tok = node.Value;

                    if (!tok.isControl)
                    {
                        count += tok.text.Length;
                        if (count - 1 == pos)
                        {
                            Token newTok = new Token();
                            newTok.isControl = true;
                            newTok.text      = _footnotes[i].render();
                            tokList.AddAfter(node, newTok);
                            break;
                        }
                        else if (count - 1 > pos)
                        {
                            LinkedListNode <Token> newNode;
                            Token newTok1 = new Token();
                            newTok1.isControl = false;
                            newTok1.text      = tok.text.Substring(0, tok.text.Length - (count - pos) + 1);
                            newNode           = tokList.AddAfter(node, newTok1);
                            Token newTok2 = new Token();
                            newTok2.isControl = true;
                            newTok2.text      = _footnotes[i].render();
                            newNode           = tokList.AddAfter(newNode, newTok2);
                            Token newTok3 = new Token();
                            newTok3.isControl = false;
                            newTok3.text      = tok.text.Substring(tok.text.Length - (count - pos) + 1);
                            newNode           = tokList.AddAfter(newNode, newTok3);
                            tokList.Remove(node);
                            break;
                        }
                    }
                    node = node.Next;
                }
            }
            #endregion
            #region Insert control words into token list.
            // --------------------------------------------------
            // Insert control words into token list.
            // --------------------------------------------------
            for (int i = 0; i < _controlWords.Count; i++)
            {
                int pos = _controlWords[i].Position;
                if (pos >= _text.Length)
                {
                    continue;
                }

                count = 0;
                node  = tokList.First;
                while (node != null)
                {
                    Token tok = node.Value;

                    if (!tok.isControl)
                    {
                        count += tok.text.Length;
                        if (count - 1 == pos)
                        {
                            Token newTok = new Token();
                            newTok.isControl = true;
                            newTok.text      = _controlWords[i].render();
                            tokList.AddAfter(node, newTok);
                            break;
                        }
                        else if (count - 1 > pos)
                        {
                            LinkedListNode <Token> newNode;
                            Token newTok1 = new Token();
                            newTok1.isControl = false;
                            newTok1.text      = tok.text.Substring(0, tok.text.Length - (count - pos) + 1);
                            newNode           = tokList.AddAfter(node, newTok1);
                            Token newTok2 = new Token();
                            newTok2.isControl = true;
                            newTok2.text      = _controlWords[i].render();
                            newNode           = tokList.AddAfter(newNode, newTok2);
                            Token newTok3 = new Token();
                            newTok3.isControl = false;
                            newTok3.text      = tok.text.Substring(tok.text.Length - (count - pos) + 1);
                            newNode           = tokList.AddAfter(newNode, newTok3);
                            tokList.Remove(node);
                            break;
                        }
                    }
                    node = node.Next;
                }
            }
            #endregion

            return(tokList);
        }
Esempio n. 2
0
		protected LinkedList<Token> buildTokenList()
		{
			int count;
			Token token;
			LinkedList<Token> tokList = new LinkedList<Token>();
			LinkedListNode<Token> node;
			List<DisjointRange> dranges = new List<DisjointRange>();

			#region Build head[] and tail[] from char format range for later use.
			// --------------------------------------------------
			// Transform possibly overlapped character format ranges into
			// disjoint ranges.
			// --------------------------------------------------
			for (int i = 0; i < _charFormats.Count; i++) {
				RtfCharFormat fmt = _charFormats[i];
				DisjointRange range = null;
				if (fmt.Begin == -1 && fmt.End == -1) {
					range = new DisjointRange();
					range.head = 0;
					range.tail = _text.Length - 1;
					range.format = fmt;
				} else if (fmt.Begin <= fmt.End) {
					range = new DisjointRange();
					range.head = fmt.Begin;
					range.tail = fmt.End;
					range.format = fmt;
				} else {
					continue;
				}
				if (range.tail >= _text.Length) {
					range.tail = _text.Length - 1;
					if (range.head > range.tail) {
						continue;
					}
				}
				// make the ranges disjoint from each other.
				List<DisjointRange> delList = new List<DisjointRange>();
				List<DisjointRange> addList = new List<DisjointRange>();
				List<DisjointRange> addAnchorList = new List<DisjointRange>();
				for (int j = 0; j < dranges.Count; j++) {
					DisjointRange r = dranges[j];
					if (range.head <= r.head && range.tail >= r.tail) {
						// former range is totally covered by the later
						//       |--------| r
						//   |-----------------| range
						delList.Add(r);
					} else if (range.head <= r.head && range.tail >= r.head && range.tail < r.tail) {
						// former range is partially covered
						//          |------------------| r
						//     |-----------------| range
						r.head = range.tail + 1;
					} else if (range.head > r.head && range.head <= r.tail && range.tail >= r.tail) {
						// former range is partially covered
						//     |------------------| r
						//          |-----------------| range
						r.tail = range.head - 1;
					} else if (range.head > r.head && range.tail < r.tail) {
						// later range is totally covered by the former
						//   |----------------------| r
						//        |---------| range
						DisjointRange newRange = new DisjointRange();
						newRange.head = range.tail + 1;
						newRange.tail = r.tail;
						newRange.format = r.format;
						r.tail = range.head - 1;
						addList.Add(newRange);
						addAnchorList.Add(r);
					}
				}
				dranges.Add(range);
				for (int j = 0; j < delList.Count; j++) {
					dranges.Remove(delList[j]);
				}
				for (int j = 0; j < addList.Count; j++) {
					int index = dranges.IndexOf(addAnchorList[j]);
					if (index < 0) {
						continue;
					}
					dranges.Insert(index, addList[j]);
				}
			}
			#endregion
			token = new Token();
			token.text = _text.ToString();
			token.isControl = false;
			tokList.AddLast(token);
			#region Build token list from head[] and tail[].
			// --------------------------------------------------
			// Build token list from head[] and tail[].
			// --------------------------------------------------
			for (int i = 0; i < dranges.Count; i++) {
				DisjointRange r = dranges[i];
				count = 0;
				// process head[i]
				if (r.head == 0) {
					Token newTok = new Token();
					newTok.isControl = true;
					newTok.text = r.format.renderHead();
					tokList.AddFirst(newTok);
				} else {
					node = tokList.First;
					while (node != null) {
						Token tok = node.Value;

						if (!tok.isControl) {
							count += tok.text.Length;
							if (count == r.head) {
								Token newTok = new Token();
								newTok.isControl = true;
								newTok.text = r.format.renderHead();
								while (node.Next != null && node.Next.Value.isControl) {
									node = node.Next;
								}
								tokList.AddAfter(node, newTok);
								break;
							} else if (count > r.head) {
								LinkedListNode<Token> newNode;
								Token newTok1 = new Token();
								newTok1.isControl = false;
								newTok1.text = tok.text.Substring(0, tok.text.Length - (count - r.head));
								newNode = tokList.AddAfter(node, newTok1);
								Token newTok2 = new Token();
								newTok2.isControl = true;
								newTok2.text = r.format.renderHead();
								newNode = tokList.AddAfter(newNode, newTok2);
								Token newTok3 = new Token();
								newTok3.isControl = false;
								newTok3.text = tok.text.Substring(tok.text.Length - (count - r.head));
								newNode = tokList.AddAfter(newNode, newTok3);
								tokList.Remove(node);
								break;
							}
						}
						node = node.Next;
					}
				}
				// process tail[i]
				count = 0;
				node = tokList.First;
				while (node != null) {
					Token tok = node.Value;

					if (!tok.isControl) {
						count += tok.text.Length;
						if (count - 1 == r.tail) {
							Token newTok = new Token();
							newTok.isControl = true;
							newTok.text = r.format.renderTail();
							tokList.AddAfter(node, newTok);
							break;
						} else if (count - 1 > r.tail) {
							LinkedListNode<Token> newNode;
							Token newTok1 = new Token();
							newTok1.isControl = false;
							newTok1.text = tok.text.Substring(0, tok.text.Length - (count - r.tail) + 1);
							newNode = tokList.AddAfter(node, newTok1);
							Token newTok2 = new Token();
							newTok2.isControl = true;
							newTok2.text = r.format.renderTail();
							newNode = tokList.AddAfter(newNode, newTok2);
							Token newTok3 = new Token();
							newTok3.isControl = false;
							newTok3.text = tok.text.Substring(tok.text.Length - (count - r.tail) + 1);
							newNode = tokList.AddAfter(newNode, newTok3);
							tokList.Remove(node);
							break;
						}
					}
					node = node.Next;
				}
			} // end for each char format
			#endregion
			#region Insert footnote into token list.
			// --------------------------------------------------
			// Insert footnote into token list.
			// --------------------------------------------------
			for (int i = 0; i < _footnotes.Count; i++) {
				int pos = _footnotes[i].Position;
				if (pos >= _text.Length) {
					continue;
				}
			
				count = 0;
				node = tokList.First;
				while (node != null) {
					Token tok = node.Value;
					
					if (!tok.isControl) {
						count += tok.text.Length;
						if (count - 1 == pos) {
							Token newTok = new Token();
							newTok.isControl = true;
							newTok.text = _footnotes[i].render();
							tokList.AddAfter(node, newTok);
							break;
						} else if (count - 1 > pos) {
							LinkedListNode<Token> newNode;
							Token newTok1 = new Token();
							newTok1.isControl = false;
							newTok1.text = tok.text.Substring(0, tok.text.Length - (count - pos) + 1);
							newNode = tokList.AddAfter(node, newTok1);
							Token newTok2 = new Token();
							newTok2.isControl = true;
							newTok2.text = _footnotes[i].render();
							newNode = tokList.AddAfter(newNode, newTok2);
							Token newTok3 = new Token();
							newTok3.isControl = false;
							newTok3.text = tok.text.Substring(tok.text.Length - (count - pos) + 1);
							newNode = tokList.AddAfter(newNode, newTok3);
							tokList.Remove(node);
							break;
						}
					}
					node = node.Next;
				}
			}
			#endregion
			#region Insert control words into token list.
			// --------------------------------------------------
			// Insert control words into token list.
			// --------------------------------------------------
			for (int i = 0; i < _controlWords.Count; i++) {
				int pos = _controlWords[i].Position;
				if (pos >= _text.Length) {
					continue;
				}

				count = 0;
				node = tokList.First;
				while (node != null) {
					Token tok = node.Value;

					if (!tok.isControl) {
						count += tok.text.Length;
						if (count - 1 == pos) {
							Token newTok = new Token();
							newTok.isControl = true;
							newTok.text = _controlWords[i].render();
							tokList.AddAfter(node, newTok);
							break;
						} else if (count - 1 > pos) {
							LinkedListNode<Token> newNode;
							Token newTok1 = new Token();
							newTok1.isControl = false;
							newTok1.text = tok.text.Substring(0, tok.text.Length - (count - pos) + 1);
							newNode = tokList.AddAfter(node, newTok1);
							Token newTok2 = new Token();
							newTok2.isControl = true;
							newTok2.text = _controlWords[i].render();
							newNode = tokList.AddAfter(newNode, newTok2);
							Token newTok3 = new Token();
							newTok3.isControl = false;
							newTok3.text = tok.text.Substring(tok.text.Length - (count - pos) + 1);
							newNode = tokList.AddAfter(newNode, newTok3);
							tokList.Remove(node);
							break;
						}
					}
					node = node.Next;
				}
			}
			#endregion
					
			return tokList;
		}