Exemplo n.º 1
0
        public void ParseParams()
        {
            var str = "a = abc; b = 123; c = { color: red; };";

            var res = ParamsParser.Parse(str);

            res.Count.ShouldEqual(3);

            res["a"].ShouldEqual("abc");
            res["b"].ShouldEqual("123");
            res["c"].ShouldEqual("color: red;");
        }
Exemplo n.º 2
0
        public ParseContentRes ParseContent(string str, VarStorg vars)
        {
            VarStorg localVars = null;

            var res      = string.Empty;
            var inherits = new List <string>();

            for (var i = 0; i < str.Length; i++)
            {
                var skipChar = false;
                var varfound = false;

                if (str.IsNextStr(i, OssConst.InheritKey))
                {
                    // inherit

                    i += OssConst.InheritKey.Length;
                    var name = str.GetNextWordToSemicol(i, out i);
                    inherits.Add(name);
                    res = res.TrimEnd(StrConst.EmptyChars); // rem space left from inherit line
                    continue;
                }

                if (str.IsNextStr(i, OssConst.CalcKey))
                {
                    i += OssConst.CalcKey.Length - 1;
                    var endi = StrUtil.GetBlockEndPrn(str, i);
                    if (endi < 0)
                    {
                        throw new Exception("can't find end of calc(");
                    }

                    var expr = str.FromTo(i + 1, endi - 1);

                    var pexpr = ParseContent(expr, vars).Content;

                    var val = ExprCalc.Eval(pexpr);

                    if (val == (int)val)
                    {
                        res = res + val;
                    }
                    else
                    {
                        res = res + val.ToString("0.##", CultureInfo.InvariantCulture);
                    }

                    i        = endi;
                    skipChar = true;
                }

                var isvar    = str.IsNextStr(i, OssConst.VarKey);
                var isvarprn = str.IsNextStr(i, OssConst.VarPrnKey);

                if (isvar || isvarprn)
                {
                    // var.x

                    string varname = null;
                    if (isvar)
                    {
                        i += OssConst.VarKey.Length;
                        foreach (var key in vars.Keys)
                        {
                            if (!str.IsNextStr(i, key))
                            {
                                continue;
                            }
                            i       += key.Length - 1;
                            varname  = key;
                            varfound = true;
                            skipChar = true;
                            break;
                        }
                    }
                    else
                    {
                        i += OssConst.VarPrnKey.Length;
                        var endi = StrUtil.GetBlockEndPrn(str, i);
                        varname = str.FromTo(i, endi - 1).Trim();

                        i = endi;

                        var psi = str.FindNextNonEmpty("{", i + 1);

                        if (psi > -1)
                        {
                            var pei = str.GetBlockEnd(psi);

                            if (pei < 0)
                            {
                                logger.Error($"can't find closing bracket for var({varname}) parameters ')' ");
                            }

                            var pcon = str.FromTo(psi + 1, pei - 1);

                            var parms = ParamsParser.Parse(pcon);

                            localVars = new VarStorg();

                            foreach (var parm in parms)
                            {
                                var osv = new OssVar();
                                osv.Name    = parm.Key;
                                osv.IsRules = parm.Value.Contains("{");
                                osv.Val     = osv.IsRules ? new ParseContentRes {
                                    Content = parm.Value
                                } : ParseContent(parm.Value, vars);
                                //osv.Val.RawContent = parm.Value;
                                localVars.Add(parm.Key, osv);
                            }

                            i = pei;
                        }

                        varfound = true;
                        skipChar = true;
                    }

                    if (varfound)
                    {
                        var vpr = vars[varname].Val;
                        var val = vpr.Content;

                        if (localVars != null)
                        {
                            // merge vars into localVars, without vars that exist in localVars

                            //foreach (var item in vars)
                            //{
                            //    if (!localVars.ContainsKey(item.Key))
                            //    {
                            //        localVars.Add(item);
                            //    }
                            //}

                            localVars.SetBase(vars);

                            val = ParseContent(vpr.RawContent, localVars).Content;
                        }
                        else if (vpr.IsRaw)
                        {
                            val = ParseContent(vpr.RawContent, vars).Content;
                        }

                        // get indentation
                        if (val.Contains(';'))
                        {
                            var nli = res.LastIndexOf('\n');
                            if (nli > 0)
                            {
                                var space = res.Substring(nli + 1);
                                if (space.Length > 0 && space.Trim(' ', '\t').Length == 0)
                                {
                                    // set indentation in val
                                    var arr = val.Split('\n');
                                    for (var j = 1; j < arr.Length; j++)
                                    {
                                        arr[j] = space + arr[j].TrimStart();
                                    }

                                    val = string.Join("\n", arr);
                                }
                            }
                        }

                        if (val == "rem")
                        {
                            res = res.TrimEnd();
                            var spacei = res.LastIndexOfAny(new[] { ' ', '\t' });
                            if (spacei > 0)
                            {
                                res = res.Remove(spacei).TrimEnd(new[] { ' ', '\t' });
                            }

                            val = string.Empty;
                        }

                        res += val;

                        if (vpr.Inherits != null)
                        {
                            inherits.AddRange(vpr.Inherits);
                        }

                        if ((val.EndsWith(";") || val == string.Empty) && str.Length > i + 1 && str[i + 1] == ';')
                        {
                            i++;
                        }

                        if (val == string.Empty)
                        {
                            var nli = str.IndexOf("\n", i, StringComparison.Ordinal);
                            if (nli > 0)
                            {
                                if (str.FromTo(i + 1, nli).Trim(StrConst.EmptyChars) == string.Empty)
                                {
                                    i   = nli;
                                    res = res.TrimEnd(' ', '\t');
                                }
                            }
                        }
                    }
                    else
                    {
                        logger.Error("could not find var at " + str.GetNextWordToSemicol(i, out _));
                    }
                }

                if (!skipChar)
                {
                    res += str[i];
                }
            }

            return(new ParseContentRes {
                Content = res, Inherits = inherits
            });
        }