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);
    }
예제 #2
0
            /// <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);
            }
예제 #3
0
            /// <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();
            }
예제 #4
0
        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());
    }
예제 #6
0
            /// <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);
            }
예제 #7
0
            /// <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;
            }
예제 #8
0
            /// <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);
    }
예제 #12
0
            /// <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);
 }
예제 #15
0
파일: RtfTree.cs 프로젝트: sonygod/dotahit
            /// <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;
            }
예제 #16
0
            /// <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;
            }
예제 #17
0
파일: RtfTree.cs 프로젝트: gipasoft/Sfera
            /// <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);
 }
예제 #20
0
파일: RtfLex.cs 프로젝트: sonygod/dotahit
            /// <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);
 }
예제 #23
0
            /// <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();
            }
예제 #24
0
            /// <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();
                }
            }
예제 #25
0
            /// <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);
            }
예제 #26
0
            /// <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());
 }
예제 #28
0
파일: RtfLex.cs 프로젝트: sonygod/dotahit
            /// <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();
                }
            }
예제 #29
0
            /// <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;
            }
예제 #30
0
파일: RtfLex.cs 프로젝트: sonygod/dotahit
            /// <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;
            }
예제 #31
0
            /// <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;
            }