/// <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.Dispose(); return(res); }
/// <summary> /// Lee un nuevo token del documento RTF. /// </summary> /// <returns>Siguiente token leido del documento.</returns> public RtfToken NextToken() { //Se crea el nuevo token a devolver RtfToken token = new RtfToken(); //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; c = rtf.Read(); break; case '}': token.Type = RtfTokenType.GroupEnd; c = rtf.Read(); break; case '\\': parseKeyword(token); break; default: token.Type = RtfTokenType.Text; parseText(token); break; } } else { //Fin de fichero token.Type = RtfTokenType.Eof; } 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(); }
/// <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) { //Se limpian los StringBuilders keysb.Length = 0; parsb.Length = 0; int parametroInt = 0; bool negativo = false; c = rtf.Read(); //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)) { 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? } c = rtf.Read(); } else //El caracter leido es una letra { //Se lee la palabra clave completa (hasta encontrar un caracter no alfanumérico, por ejemplo '\' ó ' ' while (Char.IsLetter((char)c)) { keysb.Append((char)c); c = rtf.Read(); } //Se asigna la palabra clave leida token.Type = RtfTokenType.Keyword; token.Key = keysb.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; c = rtf.Read(); } //Se lee el parámetro completo while (Char.IsDigit((char)c)) { parsb.Append((char)c); c = rtf.Read(); } parametroInt = Convert.ToInt32(parsb.ToString()); if (negativo) { parametroInt = -parametroInt; } //Se asigna el parámetro de la palabra clave token.Parameter = parametroInt; } if (c == ' ') { c = rtf.Read(); } } }