bool IgnoredDelimiterIsRequired(RtfTokenizer tokenizer, RtfToken token, RtfToken previous) { // Word inserts required delimiters when required, and optional delimiters for beautification // and readability. Strip the optional delimiters while retaining the required ones. if (previous.Type != RtfTokenType.ControlWord) { return(false); } var current = tokenizer.Current; try { while (tokenizer.MoveNext()) { var next = tokenizer.Current; var canMerge = CanMergeToControlWord(previous, next); if (canMerge == null) { continue; } return(canMerge.Value); } } finally { tokenizer.MoveTo(current); } return(false); }
/// <summary> /// Obtiene el siguiente elemento del documento. /// </summary> /// <returns>Siguiente elemento del documento.</returns> public int Next() { tok = lex.NextToken(); switch (tok.Type) { case RtfTokenType.GroupStart: currentEvent = START_GROUP; break; case RtfTokenType.GroupEnd: currentEvent = END_GROUP; break; case RtfTokenType.Keyword: currentEvent = KEYWORD; break; case RtfTokenType.Control: currentEvent = CONTROL; break; case RtfTokenType.Text: currentEvent = TEXT; break; case RtfTokenType.Eof: currentEvent = END_DOCUMENT; break; } return(currentEvent); }
/// <summary> /// Lee una cadena de Texto del documento RTF. /// </summary> /// <param name="car">Primer caracter de la cadena.</param> /// <param name="token">Token RTF al que se asignará la palabra clave.</param> private void parseText(int car, RtfToken token) { int c = car; StringBuilder Texto = new StringBuilder(((char)c).ToString(), 3000000); c = rtf.Peek(); //Se ignoran los retornos de carro, tabuladores y caracteres nulos while (c == '\r' || c == '\n' || c == '\t' || c == '\0') { rtf.Read(); c = rtf.Peek(); } while (c != '\\' && c != '}' && c != '{' && c != Eof) { rtf.Read(); Texto.Append((char)c); c = rtf.Peek(); //Se ignoran los retornos de carro, tabuladores y caracteres nulos while (c == '\r' || c == '\n' || c == '\t' || c == '\0') { rtf.Read(); c = rtf.Peek(); } } token.Key = Texto.ToString(); }
public bool AppendRtfTokenText(RtfToken token, int maxSize) { int num = 0; int num2; while ((num2 = this.GetSpace(maxSize)) != 0 && (num2 = token.Text.Read(this.buffer, this.count, num2)) != 0) { this.count += num2; num += num2; } return(num != 0); }
public string GetNormalizedString() { StringBuilder sb = new StringBuilder(); var tokenizer = new RtfTokenizer(Rtf); RtfToken previous = RtfToken.None; while (tokenizer.MoveNext()) { previous = AddCurrentToken(tokenizer, sb, previous); } return(sb.ToString()); }
/// <summary> /// Comienza el análisis del documento RTF y provoca la llamada a los distintos métodos /// del objeto IRtfReader indicado en el constructor de la clase. /// </summary> /// <returns> /// Resultado del análisis del documento. Si la carga se realiza correctamente /// se devuelve el valor 0. /// </returns> public int Parse() { //Resultado del análisis int res = 0; //Comienza el documento reader.StartRtfDocument(); //Se obtiene el primer token tok = lex.NextToken(); while (tok.Type != RtfTokenType.Eof) { switch (tok.Type) { case RtfTokenType.GroupStart: reader.StartRtfGroup(); break; case RtfTokenType.GroupEnd: reader.EndRtfGroup(); break; case RtfTokenType.Keyword: reader.RtfKeyword(tok.Key, tok.HasParameter, tok.Parameter); break; case RtfTokenType.Control: reader.RtfControl(tok.Key, tok.HasParameter, tok.Parameter); break; case RtfTokenType.Text: reader.RtfText(tok.Key); break; default: res = -1; break; } //Se obtiene el siguiente token tok = lex.NextToken(); } //Finaliza el documento reader.EndRtfDocument(); //Se cierra el stream rtf.Close(); return(res); }
/// <summary> /// Constructor privado de la clase RtfTreeNode. Crea un nodo a partir de un token del analizador léxico. /// </summary> /// <param name="token">Token RTF devuelto por el analizador léxico.</param> internal RtfTreeNode(RtfToken token) { children = new RtfNodeCollection(); this.type = (RtfNodeType)token.Type; this.key = token.Key; this.hasParam = token.HasParameter; this.param = token.Parameter; /* Inicializados por defecto */ //this.parent = null; //this.root = null; }
/// <summary> /// Lee un nuevo token del documento RTF. /// </summary> /// <returns>Siguiente token leido del documento.</returns> public RtfToken NextToken() { //Caracter leido del documento int c; //Se crea el nuevo token a devolver RtfToken token = new RtfToken(); //Se lee el siguiente caracter del documento c = rtf.Read(); //Se ignoran los retornos de carro, tabuladores y caracteres nulos while (c == '\r' || c == '\n' || c == '\t' || c == '\0') { c = rtf.Read(); } //Se trata el caracter leido if (c != Eof) { switch (c) { case '{': token.Type = RtfTokenType.GroupStart; break; case '}': token.Type = RtfTokenType.GroupEnd; break; case '\\': parseKeyword(token); break; default: token.Type = RtfTokenType.Text; parseText(c, token); break; } } else { //Fin de fichero token.Type = RtfTokenType.Eof; } return(token); }
private void AddControlWord(RtfTokenizer tokenizer, RtfToken token, StringBuilder sb, RtfToken previous) { // Carriage return, usually ignored. // Rich Text Format (RTF) Specification, Version 1.9.1, p 151: // RTF writers should not use the carriage return/line feed (CR/LF) combination to break up pictures // in binary format. If they do, the CR/LF combination is treated as literal text and considered part of the picture data. AddContent(tokenizer, token, sb, previous); int binaryLength; if (IsBinaryToken(token, out binaryLength)) { if (tokenizer.MoveFixedLength(binaryLength)) { AddContent(tokenizer, tokenizer.Current, sb, previous); } } }
private static bool?CanMergeToControlWord(RtfToken previous, RtfToken next) { if (previous.Type != RtfTokenType.ControlWord) { throw new ArgumentException(); } if (next.Type == RtfTokenType.CRLF) { return(null); // Can't tell } if (next.Type != RtfTokenType.Content) { return(false); } if (previous.Length < 2) { return(false); // Internal error? } if (next.Length < 1) { return(null); // Internal error? } var lastCh = previous.Rtf[previous.StartIndex + previous.Length - 1]; var nextCh = next.Rtf[next.StartIndex]; if (RtfTokenizer.IsAsciiLetter(lastCh)) { return(RtfTokenizer.IsAsciiLetter(nextCh) || RtfTokenizer.IsAsciiMinus(nextCh) || RtfTokenizer.IsAsciiDigit(nextCh)); } else if (RtfTokenizer.IsAsciiMinus(lastCh)) { return(RtfTokenizer.IsAsciiDigit(nextCh)); } else if (RtfTokenizer.IsAsciiDigit(lastCh)) { return(RtfTokenizer.IsAsciiDigit(nextCh)); } else { Debug.Assert(false, "unknown final character for control word token \"" + previous.ToString() + "\""); return(false); } }
private RtfToken AddCurrentToken(RtfTokenizer tokenizer, StringBuilder sb, RtfToken previous) { var token = tokenizer.Current; switch (token.Type) { case RtfTokenType.None: break; case RtfTokenType.StartGroup: AddPushGroup(tokenizer, token, sb, previous); break; case RtfTokenType.EndGroup: AddPopGroup(tokenizer, token, sb, previous); break; case RtfTokenType.ControlWord: AddControlWord(tokenizer, token, sb, previous); break; case RtfTokenType.ControlSymbol: AddControlSymbol(tokenizer, token, sb, previous); break; case RtfTokenType.IgnoredDelimiter: AddIgnoredDelimiter(tokenizer, token, sb, previous); break; case RtfTokenType.CRLF: AddCarriageReturn(tokenizer, token, sb, previous); break; case RtfTokenType.Content: AddContent(tokenizer, token, sb, previous); break; default: Debug.Assert(false, "Unknown token type " + token.ToString()); break; } return(token); }
/// <summary> /// Lee una cadena de Texto del documento RTF. /// </summary> /// <param name="token">Token RTF al que se asignar?la palabra clave.</param> private void parseText(RtfToken token) { //Se limpia el StringBuilder keysb.Length = 0; while (c != '\\' && c != '}' && c != '{' && c != Eof) { keysb.Append((char)c); c = rtf.Read(); //Se ignoran los retornos de carro, tabuladores y caracteres nulos while (c == '\r' || c == '\n' || c == '\t' || c == '\0') { c = rtf.Read(); } } token.Key = keysb.ToString(); }
private void AddIgnoredDelimiter(RtfTokenizer tokenizer, RtfToken token, StringBuilder sb, RtfToken previous) { // Rich Text Format (RTF) Specification, Version 1.9.1, p 151: // an RTF file does not have to contain any carriage return/line feed pairs (CRLFs) and CRLFs should be ignored by RTF readers except that // they can act as control word delimiters. RTF files are more readable when CRLFs occur at major group boundaries. // // but then later: // // If a single space delimits the control word, the space does not appear in the document (it’s ignored). Any characters following the single space delimiter, including any subsequent spaces, // will appear as text or spaces in the document. For this reason, you should use spaces only where necessary. It is recommended to avoid spaces as a means of breaking up RTF syntax to make // it easier to read. You can use paragraph marks (CR, LF, or CRLF) to break up lines without changing the meaning except in destinations that contain \binN. // In this document, a control word that takes a numeric parameter N is written with the N, as shown here for \binN, unless the control word appears with an explicit value. The only exceptions to // this are “toggle” control words like \b (bold toggle), which have only two states. When such a control word has no parameter or has a nonzero parameter, the control word turns the property on. // When such a control word has a parameter of 0, the control word turns the property off. For example, \b turns on bold and \b0 turns off bold. In the definitions of these toggle control words, // the control word names are followed by an asterisk. if (IgnoredDelimiterIsRequired(tokenizer, token, previous)) { // There *May* be a need for a delimiter, AddContent(tokenizer, " ", sb, previous); } }
bool IsBinaryToken(RtfToken token, out int binaryLength) { // Rich Text Format (RTF) Specification, Version 1.9.1, p 209: // Remember that binary data can occur when you’re skipping RTF. // A simple way to skip a group in RTF is to keep a running count of the opening braces the RTF reader // has encountered in the RTF stream. When the RTF reader sees an opening brace, it increments the count. // When the reader sees a closing brace, it decrements the count. When the count becomes negative, the end // of the group was found. Unfortunately, this does not work when the RTF file contains a \binN control; the // reader must explicitly check each control word found to see if it is a \binN control, and if found, // skip that many bytes before resuming its scanning for braces. if (string.CompareOrdinal(binPrefix, 0, token.Rtf, token.StartIndex, binPrefix.Length) == 0) { if (RtfTokenizer.IsControlWordNumericParameter(token, token.StartIndex + binPrefix.Length)) { bool ok = int.TryParse(token.Rtf.Substring(token.StartIndex + binPrefix.Length, token.Length - binPrefix.Length), NumberStyles.Integer, CultureInfo.InvariantCulture, out binaryLength); return(ok); } } binaryLength = -1; return(false); }
/// <summary> /// Analiza el documento y lo carga con estructura de árbol. /// </summary> /// <returns>Se devuelve el valor 0 en caso de no producirse ningún error en la carga del documento. /// En caso contrario se devuelve el valor -1.</returns> private int parseRtfTree() { //Resultado de la carga del documento int res = 0; //Codificación por defecto del documento Encoding encoding = Encoding.Default; //Nodo actual RtfTreeNode curNode = rootNode; //Nuevos nodos para construir el árbol RTF RtfTreeNode newNode = null; //Se obtiene el primer token tok = lex.NextToken(); while (tok.Type != RtfTokenType.Eof) { switch (tok.Type) { case RtfTokenType.GroupStart: newNode = new RtfTreeNode(RtfNodeType.Group,"GROUP",false,0); curNode.AppendChild(newNode); curNode = newNode; level++; break; case RtfTokenType.GroupEnd: curNode = curNode.ParentNode; level--; break; case RtfTokenType.Keyword: case RtfTokenType.Control: case RtfTokenType.Text: if (mergeSpecialCharacters) { //Contributed by Jan Stuchlík bool isText = tok.Type == RtfTokenType.Text || (tok.Type == RtfTokenType.Control && tok.Key == "'"); if (curNode.LastChild != null && (curNode.LastChild.NodeType == RtfNodeType.Text && isText)) { if (tok.Type == RtfTokenType.Text) { curNode.LastChild.NodeKey += tok.Key; break; } if (tok.Type == RtfTokenType.Control && tok.Key == "'") { curNode.LastChild.NodeKey += DecodeControlChar(tok.Parameter, encoding); break; } } else { //Primer caracter especial \' if (tok.Type == RtfTokenType.Control && tok.Key == "'") { newNode = new RtfTreeNode(RtfNodeType.Text, DecodeControlChar(tok.Parameter, encoding), false, 0); curNode.AppendChild(newNode); break; } } } newNode = new RtfTreeNode(tok); curNode.AppendChild(newNode); if (mergeSpecialCharacters) { //Contributed by Jan Stuchlík if (level == 1 && newNode.NodeType == RtfNodeType.Keyword && newNode.NodeKey == "ansicpg") { encoding = Encoding.GetEncoding(newNode.Parameter); } } break; default: res = -1; break; } //Se obtiene el siguiente token tok = lex.NextToken(); } //Si el nivel actual no es 0 ( == Algun grupo no está bien formado ) if (level != 0) { res = -1; } //Se devuelve el resultado de la carga return res; }
/// <summary> /// Analiza el documento y lo carga con estructura de árbol. /// </summary> /// <returns>Se devuelve el valor 0 en caso de no producirse ningún error en la carga del documento. /// En caso contrario se devuelve el valor -1.</returns> private int parseRtfTree() { //Resultado de la carga del documento int res = 0; //Nodo actual RtfTreeNode curNode = rootNode; //Nuevos nodos para construir el árbol RTF RtfTreeNode newNode = null; //Se obtiene el primer token tok = lex.NextToken(); while (tok.Type != RtfTokenType.Eof) { switch (tok.Type) { case RtfTokenType.GroupStart: newNode = new RtfTreeNode(RtfNodeType.Group); curNode.AppendChild(newNode); curNode = newNode; level++; break; case RtfTokenType.GroupEnd: curNode = curNode.ParentNode; level--; break; case RtfTokenType.Keyword: case RtfTokenType.Control: case RtfTokenType.Text: newNode = new RtfTreeNode(tok); curNode.AppendChild(newNode); break; default: res = -1; break; } //Se obtiene el siguiente token tok = lex.NextToken(); } //Si el nivel actual no es 0 ( == Algun grupo no está bien formado ) if (level != 0) { res = -1; } //Se devuelve el resultado de la carga return res; }
private void AddContent(RtfTokenizer tokenizer, string content, StringBuilder sb, RtfToken previous) { sb.Append(content); }
private void AddControlSymbol(RtfTokenizer tokenizer, RtfToken token, StringBuilder sb, RtfToken previous) { AddContent(tokenizer, token, sb, previous); }
/// <summary> /// Lee una cadena de Texto del documento RTF. /// </summary> /// <param name="car">Primer caracter de la cadena.</param> /// <param name="token">Token RTF al que se asignará la palabra clave.</param> private void parseText(int car, RtfToken token) { int c = car; StringBuilder Texto = new StringBuilder(((char)c).ToString(),3000000); c = rtf.Peek(); //Se ignoran los retornos de carro, tabuladores y caracteres nulos while (c == '\r' || c == '\n' || c == '\t' || c == '\0') { rtf.Read(); c = rtf.Peek(); } while (c != '\\' && c != '}' && c != '{' && c != Eof) { rtf.Read(); Texto.Append((char)c); c = rtf.Peek(); //Se ignoran los retornos de carro, tabuladores y caracteres nulos while (c == '\r' || c == '\n' || c == '\t' || c == '\0') { rtf.Read(); c = rtf.Peek(); } } token.Key = Texto.ToString(); }
private void AddCarriageReturn(RtfTokenizer tokenizer, RtfToken token, StringBuilder sb, RtfToken previous) { // DO NOTHING. }
private void AddPopGroup(RtfTokenizer tokenizer, RtfToken token, StringBuilder sb, RtfToken previous) { AddContent(tokenizer, token, sb, previous); }
/// <summary> /// Lee una cadena de Texto del documento RTF. /// </summary> /// <param name="token">Token RTF al que se asignará la palabra clave.</param> private void parseText(RtfToken token) { //Se limpia el StringBuilder keysb.Length = 0; while (c != '\\' && c != '}' && c != '{' && c != Eof) { keysb.Append((char)c); c = rtf.Read(); //Se ignoran los retornos de carro, tabuladores y caracteres nulos while (c == '\r' || c == '\n' || c == '\t' || c == '\0') c = rtf.Read(); } token.Key = keysb.ToString(); }
/// <summary> /// Lee una palabra clave del documento RTF. /// </summary> /// <param name="token">Token RTF al que se asignará la palabra clave.</param> private void parseKeyword(RtfToken token) { StringBuilder palabraClave = new StringBuilder(); StringBuilder parametroStr = new StringBuilder(); int parametroInt = 0; int c; bool negativo = false; c = rtf.Peek(); //Si el caracter leido no es una letra --> Se trata de un símbolo de Control o un caracter especial: '\\', '\{' o '\}' if (!Char.IsLetter((char)c)) { rtf.Read(); if (c == '\\' || c == '{' || c == '}') //Caracter especial { token.Type = RtfTokenType.Text; token.Key = ((char)c).ToString(); } else //Simbolo de control { token.Type = RtfTokenType.Control; token.Key = ((char)c).ToString(); //Si se trata de un caracter especial (codigo de 8 bits) se lee el parámetro hexadecimal if (token.Key == "\'") { string cod = ""; cod += (char)rtf.Read(); cod += (char)rtf.Read(); token.HasParameter = true; token.Parameter = Convert.ToInt32(cod, 16); } //TODO: ¿Hay más símbolos de Control con parámetros? } return; } //Se lee la palabra clave completa (hasta encontrar un caracter no alfanumérico, por ejemplo '\' ó ' ' c = rtf.Peek(); while (Char.IsLetter((char)c)) { rtf.Read(); palabraClave.Append((char)c); c = rtf.Peek(); } //Se asigna la palabra clave leida token.Type = RtfTokenType.Keyword; token.Key = palabraClave.ToString(); //Se comprueba si la palabra clave tiene parámetro if (Char.IsDigit((char)c) || c == '-') { token.HasParameter = true; //Se comprubea si el parámetro es negativo if (c == '-') { negativo = true; rtf.Read(); } //Se lee el parámetro completo c = rtf.Peek(); while (Char.IsDigit((char)c)) { rtf.Read(); parametroStr.Append((char)c); c = rtf.Peek(); } parametroInt = Convert.ToInt32(parametroStr.ToString()); if (negativo) { parametroInt = -parametroInt; } //Se asigna el parámetro de la palabra clave token.Parameter = parametroInt; } if (c == ' ') { rtf.Read(); } }
/// <summary> /// Analiza el documento y lo carga con estructura de árbol. /// </summary> /// <returns>Se devuelve el valor 0 en caso de no producirse ningún error en la carga del documento. /// En caso contrario se devuelve el valor -1.</returns> private int parseRtfTree() { //Resultado de la carga del documento int res = 0; //Codificación por defecto del documento Encoding encoding = Encoding.Default; //Nodo actual RtfTreeNode curNode = rootNode; //Nuevos nodos para construir el árbol RTF RtfTreeNode newNode = null; //Se obtiene el primer token tok = lex.NextToken(); while (tok.Type != RtfTokenType.Eof) { switch (tok.Type) { case RtfTokenType.GroupStart: newNode = new RtfTreeNode(RtfNodeType.Group, "GROUP", false, 0); curNode.AppendChild(newNode); curNode = newNode; level++; break; case RtfTokenType.GroupEnd: curNode = curNode.ParentNode; level--; break; case RtfTokenType.Keyword: case RtfTokenType.Control: case RtfTokenType.Text: if (mergeSpecialCharacters) { //Contributed by Jan Stuchlík bool isText = tok.Type == RtfTokenType.Text || (tok.Type == RtfTokenType.Control && tok.Key == "'"); if (curNode.LastChild != null && (curNode.LastChild.NodeType == RtfNodeType.Text && isText)) { if (tok.Type == RtfTokenType.Text) { curNode.LastChild.NodeKey += tok.Key; break; } if (tok.Type == RtfTokenType.Control && tok.Key == "'") { curNode.LastChild.NodeKey += DecodeControlChar(tok.Parameter, encoding); break; } } else { //Primer caracter especial \' if (tok.Type == RtfTokenType.Control && tok.Key == "'") { newNode = new RtfTreeNode(RtfNodeType.Text, DecodeControlChar(tok.Parameter, encoding), false, 0); curNode.AppendChild(newNode); break; } } } newNode = new RtfTreeNode(tok); curNode.AppendChild(newNode); if (mergeSpecialCharacters) { //Contributed by Jan Stuchlík if (level == 1 && newNode.NodeType == RtfNodeType.Keyword && newNode.NodeKey == "ansicpg") { encoding = Encoding.GetEncoding(newNode.Parameter); } } break; default: res = -1; break; } //Se obtiene el siguiente token tok = lex.NextToken(); } //Si el nivel actual no es 0 ( == Algun grupo no está bien formado ) if (level != 0) { res = -1; } //Se devuelve el resultado de la carga return(res); }
/// <summary> /// Comienza el análisis del documento RTF y provoca la llamada a los distintos métodos /// del objeto IRtfReader indicado en el constructor de la clase. /// </summary> /// <returns> /// Resultado del análisis del documento. Si la carga se realiza correctamente /// se devuelve el valor 0. /// </returns> public int Parse() { //Resultado del análisis int res = 0; //Comienza el documento reader.StartRtfDocument(); //Se obtiene el primer token tok = lex.NextToken(); while (tok.Type != RtfTokenType.Eof) { switch (tok.Type) { case RtfTokenType.GroupStart: reader.StartRtfGroup(); break; case RtfTokenType.GroupEnd: reader.EndRtfGroup(); break; case RtfTokenType.Keyword: reader.RtfKeyword(tok.Key, tok.HasParameter, tok.Parameter); break; case RtfTokenType.Control: reader.RtfControl(tok.Key, tok.HasParameter, tok.Parameter); break; case RtfTokenType.Text: reader.RtfText(tok.Key); break; default: res = -1; break; } //Se obtiene el siguiente token tok = lex.NextToken(); } //Finaliza el documento reader.EndRtfDocument(); //Se cierra el stream rtf.Close(); return res; }
private void AddContent(RtfTokenizer tokenizer, RtfToken token, StringBuilder sb, RtfToken previous) { sb.Append(token.ToString()); }
/// <summary> /// Lee una palabra clave del documento RTF. /// </summary> /// <param name="token">Token RTF al que se asignará la palabra clave.</param> private void parseKeyword(RtfToken token) { StringBuilder palabraClave = new StringBuilder(); StringBuilder parametroStr = new StringBuilder(); int parametroInt = 0; int c; bool negativo = false; c = rtf.Peek(); //Si el caracter leido no es una letra --> Se trata de un símbolo de Control o un caracter especial: '\\', '\{' o '\}' if (!Char.IsLetter((char)c)) { rtf.Read(); if(c == '\\' || c == '{' || c == '}') //Caracter especial { token.Type = RtfTokenType.Text; token.Key = ((char)c).ToString(); } else //Simbolo de control { token.Type = RtfTokenType.Control; token.Key = ((char)c).ToString(); //Si se trata de un caracter especial (codigo de 8 bits) se lee el parámetro hexadecimal if (token.Key == "\'") { string cod = ""; cod += (char)rtf.Read(); cod += (char)rtf.Read(); token.HasParameter = true; token.Parameter = Convert.ToInt32(cod, 16); } //TODO: ¿Hay más símbolos de Control con parámetros? } return; } //Se lee la palabra clave completa (hasta encontrar un caracter no alfanumérico, por ejemplo '\' ó ' ' c = rtf.Peek(); while (Char.IsLetter((char)c)) { rtf.Read(); palabraClave.Append((char)c); c = rtf.Peek(); } //Se asigna la palabra clave leida token.Type = RtfTokenType.Keyword; token.Key = palabraClave.ToString(); //Se comprueba si la palabra clave tiene parámetro if (Char.IsDigit((char)c) || c == '-') { token.HasParameter = true; //Se comprubea si el parámetro es negativo if (c == '-') { negativo = true; rtf.Read(); } //Se lee el parámetro completo c = rtf.Peek(); while (Char.IsDigit((char)c)) { rtf.Read(); parametroStr.Append((char)c); c = rtf.Peek(); } parametroInt = Convert.ToInt32(parametroStr.ToString()); if (negativo) parametroInt = -parametroInt; //Se asigna el parámetro de la palabra clave token.Parameter = parametroInt; } if (c == ' ') { rtf.Read(); } }
/// <summary> /// Obtiene el siguiente elemento del documento. /// </summary> /// <returns>Siguiente elemento del documento.</returns> public int Next() { tok = lex.NextToken(); switch (tok.Type) { case RtfTokenType.GroupStart: currentEvent = START_GROUP; break; case RtfTokenType.GroupEnd: currentEvent = END_GROUP; break; case RtfTokenType.Keyword: currentEvent = KEYWORD; break; case RtfTokenType.Control: currentEvent = CONTROL; break; case RtfTokenType.Text: currentEvent = TEXT; break; case RtfTokenType.Eof: currentEvent = END_DOCUMENT; break; } return currentEvent; }
/// <summary> /// Lee un nuevo token del documento RTF. /// </summary> /// <returns>Siguiente token leido del documento.</returns> public RtfToken NextToken() { //Caracter leido del documento int c; //Se crea el nuevo token a devolver RtfToken token = new RtfToken(); //Se lee el siguiente caracter del documento c = rtf.Read(); //Se ignoran los retornos de carro, tabuladores y caracteres nulos while (c == '\r' || c == '\n' || c == '\t' || c == '\0') c = rtf.Read(); //Se trata el caracter leido if (c != Eof) { switch (c) { case '{': token.Type = RtfTokenType.GroupStart; break; case '}': token.Type = RtfTokenType.GroupEnd; break; case '\\': parseKeyword(token); break; default: token.Type = RtfTokenType.Text; parseText(c, token); break; } } else { //Fin de fichero token.Type = RtfTokenType.Eof; } return token; }
/// <summary> /// Constructor privado de la clase RtfTreeNode. Crea un nodo a partir de un token del analizador léxico. /// </summary> /// <param name="token">Token RTF devuelto por el analizador léxico.</param> internal RtfTreeNode(RtfToken token) { type = (RtfNodeType)token.Type; key = token.Key; hasParam = token.HasParameter; param = token.Parameter; /* Inicializados por defecto */ //this.parent = null; //this.root = null; //this.tree = null; //this.children = null; }