/**
         * Returns a version of the original string that has any special characters
         * quoted (or escaped) as appropriate for the cell format type.  The format
         * type object is queried to see what is special.
         *
         * @param repl The original string.
         * @param type The format type representation object.
         *
         * @return A version of the string with any special characters Replaced.
         *
         * @see CellFormatType#isSpecial(char)
         */
        static String QuoteSpecial(String repl, CellFormatType type)
        {
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < repl.Length; i++)
            {
                char ch = repl[i];
                if (ch == '\'' && type.IsSpecial('\''))
                {
                    sb.Append('\u0000');
                    continue;
                }

                bool special = type.IsSpecial(ch);
                if (special)
                {
                    sb.Append("'");
                }
                sb.Append(ch);
                if (special)
                {
                    sb.Append("'");
                }
            }
            return(sb.ToString());
        }
Esempio n. 2
0
        /**
         * Returns the formatter object implied by the format specification for the
         * format part.
         *
         * @param matcher The matcher for the format part.
         *
         * @return The formatter.
         */
        private CellFormatter GetFormatter(Match matcher)
        {
            String         fdesc = matcher.Groups[(SPECIFICATION_GROUP)].Value;
            CellFormatType type  = formatType(fdesc);

            return(type.Formatter(fdesc));
        }
Esempio n. 3
0
            public String HandlePart(Match m, String part, CellFormatType type,
                                     StringBuilder desc)
            {
                int  pos     = desc.Length;
                char firstCh = part[0];

                switch (firstCh)
                {
                case '[':
                    if (part.Length < 3)
                    {
                        break;
                    }
                    if (_formatter.topmost != null)
                    {
                        throw new ArgumentException(
                                  "Duplicate '[' times in format");
                    }
                    part = part.ToLower();
                    int specLen = part.Length - 2;
                    _formatter.topmost = _formatter.AssignSpec(part[1], pos, specLen);
                    return(part.Substring(1, specLen));

                case 'h':
                case 'm':
                case 's':
                case '0':
                    part = part.ToLower();
                    _formatter.AssignSpec(part[0], pos, part.Length);
                    return(part);

                case '\n':
                    return("%n");

                case '\"':
                    part = part.Substring(1, part.Length - 2);
                    break;

                case '\\':
                    part = part.Substring(1);
                    break;

                case '*':
                    if (part.Length > 1)
                    {
                        part = CellFormatPart.ExpandChar(part);
                    }
                    break;

                // An escape we can let it handle because it can't have a '%'
                case '_':
                    return(null);
                }
                // Replace ever "%" with a "%%" so we can use printf
                //return PERCENTS.Matcher(part).ReplaceAll("%%");
                //return PERCENTS.Replace(part, "%%");
                return(part);
            }
Esempio n. 4
0
 public String HandlePart(Match m, String part,
                          CellFormatType type, StringBuilder desc)
 {
     if (part.Equals("@"))
     {
         numplace++;
         return("\u0000");
     }
     return(null);
 }
Esempio n. 5
0
 public String HandlePart(Match m, String part,
                     CellFormatType type, StringBuilder desc)
 {
     if (part.Equals("@"))
     {
         numplace++;
         return "\u0000";
     }
     return null;
 }
Esempio n. 6
0
        /**
         * Create an object to represent a format part.
         *
         * @param desc The string to Parse.
         */
        public CellFormatPart(String desc)
        {
            Match m = FORMAT_PAT.Match(desc);

            if (!m.Success)
            {
                throw new ArgumentException("Unrecognized format: " + "\"" + desc + "\"");
            }
            condition = GetCondition(m);
            type      = GetCellFormatType(m);
            format    = GetFormatter(m);
        }
            public String HandlePart(Match m, String part, CellFormatType type,
                    StringBuilder desc)
            {

                int pos = desc.Length;
                char firstCh = part[0];
                switch (firstCh)
                {
                    case '[':
                        if (part.Length < 3)
                            break;
                        if (_formatter.topmost != null)
                            throw new ArgumentException(
                                    "Duplicate '[' times in format");
                        part = part.ToLower();
                        int specLen = part.Length - 2;
                        _formatter.topmost = _formatter.AssignSpec(part[1], pos, specLen);
                        return part.Substring(1, specLen);

                    case 'h':
                    case 'm':
                    case 's':
                    case '0':
                        part = part.ToLower();
                        _formatter.AssignSpec(part[0], pos, part.Length);
                        return part;

                    case '\n':
                        return "%n";

                    case '\"':
                        part = part.Substring(1, part.Length - 2);
                        break;

                    case '\\':
                        part = part.Substring(1);
                        break;

                    case '*':
                        if (part.Length > 1)
                            part = CellFormatPart.ExpandChar(part);
                        break;

                    // An escape we can let it handle because it can't have a '%'
                    case '_':
                        return null;
                }
                // Replace ever "%" with a "%%" so we can use printf
                //return PERCENTS.Matcher(part).ReplaceAll("%%");
                //return PERCENTS.Replace(part, "%%");
                return part;
            }
Esempio n. 8
0
            public String HandlePart(Match m, String part, CellFormatType type, StringBuilder desc)
            {

                int pos = desc.Length;
                char firstCh = part[0];
                switch (firstCh)
                {
                    case 's':
                    case 'S':
                        if (mStart >= 0)
                        {
                            for (int i = 0; i < mLen; i++)
                                desc[mStart + i] = 'm';
                            mStart = -1;
                        }
                        return part.ToLower();

                    case 'h':
                    case 'H':
                        mStart = -1;
                        hStart = pos;
                        hLen = part.Length;
                        return part.ToLower();

                    case 'd':
                    case 'D':
                        mStart = -1;
                        if (part.Length <= 2)
                            return part.ToLower();
                        else
                            return part.ToLower().Replace('d', 'E');

                    case 'm':
                    case 'M':
                        mStart = pos;
                        mLen = part.Length;
                        return part.ToUpper();

                    case 'y':
                    case 'Y':
                        mStart = -1;
                        if (part.Length == 3)
                            part = "yyyy";
                        return part.ToLower();

                    case '0':
                        mStart = -1;
                        int sLen = part.Length;
                        _formatter.sFmt = "%0" + (sLen + 2) + "." + sLen + "f";
                        return part.Replace('0', 'f');

                    case 'a':
                    case 'A':
                    case 'p':
                    case 'P':
                        if (part.Length > 1)
                        {
                            // am/pm marker
                            mStart = -1;
                            _formatter.ShowAmPm = true;
                            _formatter.ShowM = char.ToLower(part[1]) == 'm';
                            // For some reason "am/pm" becomes AM or PM, but "a/p" becomes a or p
                            _formatter.amPmUpper = _formatter.ShowM || char.IsUpper(part[0]);
                            if (_formatter.ShowM)
                                return "tt";
                            else
                                return "t";
                            //return "a";
                        }
                    //noinspection fallthrough
                        return null;
                    default:
                        return null;
                }
            }
Esempio n. 9
0
            public String HandlePart(Match m, String part, CellFormatType type, StringBuilder desc)
            {
                int  pos     = desc.Length;
                char firstCh = part[0];

                switch (firstCh)
                {
                case 's':
                case 'S':
                    if (mStart >= 0)
                    {
                        for (int i = 0; i < mLen; i++)
                        {
                            desc[mStart + i] = 'm';
                        }
                        mStart = -1;
                    }
                    return(part.ToLower());

                case 'h':
                case 'H':
                    mStart = -1;
                    hStart = pos;
                    hLen   = part.Length;
                    return(part.ToLower());

                case 'd':
                case 'D':
                    mStart = -1;
                    //if (part.Length <= 2)
                    return(part.ToLower());

                //else
                //    return part.ToLower().Replace('d', 'E');

                case 'm':
                case 'M':
                    mStart = pos;
                    mLen   = part.Length;
                    // For 'm' after 'h', output minutes ('m') not month ('M')
                    if (hStart >= 0)
                    {
                        return(part.ToLower());
                    }
                    else
                    {
                        return(part.ToUpper());
                    }

                case 'y':
                case 'Y':
                    mStart = -1;
                    if (part.Length == 3)
                    {
                        part = "yyyy";
                    }
                    return(part.ToLower());

                case '0':
                    mStart = -1;
                    int sLen = part.Length;
                    _formatter.sFmt = "%0" + (sLen + 2) + "." + sLen + "f";
                    return(part.Replace('0', 'f'));

                case 'a':
                case 'A':
                case 'p':
                case 'P':
                    if (part.Length > 1)
                    {
                        // am/pm marker
                        mStart = -1;
                        _formatter.ShowAmPm = true;
                        _formatter.ShowM    = char.ToLower(part[1]) == 'm';
                        // For some reason "am/pm" becomes AM or PM, but "a/p" becomes a or p
                        _formatter.amPmUpper = _formatter.ShowM || char.IsUpper(part[0]);
                        if (_formatter.ShowM)
                        {
                            return("tt");
                        }
                        else
                        {
                            return("t");
                        }
                        //return "a";
                    }
                    //noinspection fallthrough
                    return(null);

                default:
                    return(null);
                }
            }
        public static StringBuilder ParseFormat(String fdesc, CellFormatType type,
                                                IPartHandler partHandler)
        {
            // Quoting is very awkward.  In the Java classes, quoting is done
            // between ' chars, with '' meaning a single ' char. The problem is that
            // in Excel, it is legal to have two adjacent escaped strings.  For
            // example, consider the Excel format "\a\b#".  The naive (and easy)
            // translation into Java DecimalFormat is "'a''b'#".  For the number 17,
            // in Excel you would Get "ab17", but in Java it would be "a'b17" -- the
            // '' is in the middle of the quoted string in Java.  So the trick we
            // use is this: When we encounter a ' char in the Excel format, we
            // output a \u0000 char into the string.  Now we know that any '' in the
            // output is the result of two adjacent escaped strings.  So After the
            // main loop, we have to do two passes: One to eliminate any ''
            // sequences, to make "'a''b'" become "'ab'", and another to replace any
            // \u0000 with '' to mean a quote char.  Oy.
            //
            // For formats that don't use "'" we don't do any of this

            MatchCollection mc        = SPECIFICATION_PAT.Matches(fdesc);
            StringBuilder   fmt       = new StringBuilder();
            Match           lastMatch = null;

            //while (m.Find())
            foreach (Match m in mc)
            {
                String part = Group(m, 0);
                if (part.Length > 0)
                {
                    String repl = partHandler.HandlePart(m, part, type, fmt);
                    if (repl == null)
                    {
                        switch (part[0])
                        {
                        case '\"':
                            repl = QuoteSpecial(part.Substring(1,
                                                               part.Length - 2), type);
                            break;

                        case '\\':
                            repl = QuoteSpecial(part.Substring(1), type);
                            break;

                        case '_':
                            repl = " ";
                            break;

                        case '*':     //!! We don't do this for real, we just Put in 3 of them
                            repl = ExpandChar(part);
                            break;

                        default:
                            repl = part;
                            break;
                        }
                    }
                    //m.AppendReplacement(fmt, Match.QuoteReplacement(repl));
                    fmt.Append(part.Replace(m.Captures[0].Value, repl));
                    if (m.NextMatch().Index - (m.Index + part.Length) > 0)
                    {
                        fmt.Append(fdesc.Substring(m.Index + part.Length, m.NextMatch().Index - (m.Index + part.Length)));
                    }
                    lastMatch = m;
                }
            }
            if (lastMatch != null)
            {
                fmt.Append(fdesc.Substring(lastMatch.Index + lastMatch.Groups[0].Value.Length));
            }
            //m.AppendTail(fmt);

            if (type.IsSpecial('\''))
            {
                // Now the next pass for quoted characters: Remove '' chars, making "'a''b'" into "'ab'"
                int pos = 0;
                while ((pos = fmt.ToString().IndexOf("''", pos)) >= 0)
                {
                    //fmt.Delete(pos, pos + 2);
                    fmt.Remove(pos, 2);
                }

                // Now the pass for quoted chars: Replace any \u0000 with ''
                pos = 0;
                while ((pos = fmt.ToString().IndexOf("\u0000", pos)) >= 0)
                {
                    //fmt.Replace(pos, pos + 1, "''");
                    fmt.Remove(pos, 1);
                    fmt.Insert(pos, "''");
                }
            }

            return(fmt);
        }
Esempio n. 11
0
        public String HandlePart(Match m, String part, CellFormatType type, StringBuilder descBuf)
        {
            int  pos     = descBuf.Length;
            char firstCh = part[0];

            switch (firstCh)
            {
            case 'e':
            case 'E':
                // See comment in WriteScientific -- exponent handling is complex.
                // (1) When parsing the format, remove the sign from After the 'e' and
                // Put it before the first digit of the exponent.
                if (exponent == null && specials.Count > 0)
                {
                    exponent = new Special('.', pos);
                    specials.Add(exponent);
                    insertSignForExponent = part[1];
                    return(part.Substring(0, 1));
                }
                break;

            case '0':
            case '?':
            case '#':
                if (insertSignForExponent != '\0')
                {
                    specials.Add(new Special(insertSignForExponent, pos));
                    descBuf.Append(insertSignForExponent);
                    insertSignForExponent = '\0';
                    pos++;
                }
                for (int i = 0; i < part.Length; i++)
                {
                    char ch = part[i];
                    specials.Add(new Special(ch, pos + i));
                }
                break;

            case '.':
                if (decimalPoint == null && specials.Count > 0)
                {
                    decimalPoint = new Special('.', pos);
                    specials.Add(decimalPoint);
                }
                break;

            case '/':
                //!! This assumes there is a numerator and a denominator, but these are actually optional
                if (slash == null && specials.Count > 0)
                {
                    numerator = PreviousNumber();
                    // If the first number in the whole format is the numerator, the
                    // entire number should be printed as an improper fraction
                    improperFraction |= (numerator == FirstDigit(specials));
                    slash             = new Special('.', pos);
                    specials.Add(slash);
                }
                break;

            case '%':
                // don't need to remember because we don't need to do anything with these
                scale *= 100;
                break;

            default:
                return(null);
            }
            return(part);
        }