Пример #1
0
 public DekiScriptLiteral this[DekiScriptLiteral index] {
     get {
         if (index == null)
         {
             throw new ArgumentNullException("index");
         }
         if ((index.ScriptType == DekiScriptType.NUM) || (index.ScriptType == DekiScriptType.STR))
         {
             return(this[SysUtil.ChangeType <string>(index.NativeValue)]);
         }
         else
         {
             throw new DekiScriptBadTypeException(Location.None, index.ScriptType, new[] { DekiScriptType.NUM, DekiScriptType.STR });
         }
     }
     set {
         if (index == null)
         {
             throw new ArgumentNullException("index");
         }
         if ((index.ScriptType == DekiScriptType.NUM) || (index.ScriptType == DekiScriptType.STR))
         {
             this[SysUtil.ChangeType <string>(index.NativeValue)] = value;
         }
         else
         {
             throw new DekiScriptBadTypeException(Location.None, index.ScriptType, new[] { DekiScriptType.NUM, DekiScriptType.STR });
         }
     }
 }
Пример #2
0
 //--- Extension Methods ---
 public static StringBuilder AppendLiteral(this StringBuilder builder, DekiScriptLiteral literal) {
     if(literal is DekiScriptString) {
         builder.Append(((DekiScriptString)literal).Value);
     } else {
         builder.Append(literal.ToString());
     }
     return builder;
 }
 //--- Methods ---
 public virtual DekiScriptLiteral Invoke(DekiScriptRuntime runtime, DekiScriptLiteral args) {
     if(args is DekiScriptList) {
         return InvokeList(runtime, (DekiScriptList)args);
     } else if(args is DekiScriptMap) {
         return InvokeMap(runtime, (DekiScriptMap)args);
     } else {
         throw new DekiScriptBadTypeException(Location.None, args.ScriptType, new[] { DekiScriptType.MAP, DekiScriptType.LIST });
     }
 }
 //--- Class Methods ---
 private static void XmlRpcLiteralRecurse(XDoc xdoc, DekiScriptLiteral value, bool isArgumentList) {
     if(!isArgumentList) {
         xdoc.Start("value");
     }
     switch(value.ScriptType) {
     case DekiScriptType.BOOL:
         xdoc.Elem("boolean", ((DekiScriptBool)value).Value ? "1" : "0");
         break;
     case DekiScriptType.NUM:
         xdoc.Elem("double", ((DekiScriptNumber)value).Value);
         break;
     case DekiScriptType.STR:
         xdoc.Elem("string", ((DekiScriptString)value).Value); // in order to work with php, this may need to be encoded
         break;
     case DekiScriptType.NIL:
         xdoc.Elem("nil");
         break;
     case DekiScriptType.URI:
         xdoc.Start("string").Attr("type", "uri").End();
         break;
     case DekiScriptType.XML:
         xdoc.Start("string").Attr("type", "xml").Value(value.NativeValue.ToString()).End();
         break;
     case DekiScriptType.LIST:
         xdoc.Start(isArgumentList ? "params" : "array");
         if(!isArgumentList)
             xdoc.Start("data");
         foreach(DekiScriptLiteral entry in ((DekiScriptList)value).Value) {
             if(isArgumentList) {
                 xdoc.Start("param");
                 XmlRpcLiteralRecurse(xdoc, entry, false);
                 xdoc.End();
             } else {
                 XmlRpcLiteralRecurse(xdoc, entry, false);
             }
         }
         if(!isArgumentList)
             xdoc.End();
         xdoc.End();
         break;
     case DekiScriptType.MAP:
         xdoc.Start("struct");
         foreach(KeyValuePair<string, DekiScriptLiteral> entry in ((DekiScriptMap)value).Value) {
             xdoc.Start("member");
             xdoc.Elem("name", entry.Key);
             XmlRpcLiteralRecurse(xdoc, entry.Value, false);
             xdoc.End();
         }
         xdoc.End();
         break;
     default:
         throw new ShouldNeverHappenException("unkwown type");
     }
     if(!isArgumentList)
         xdoc.End();
     return;
 }
Пример #5
0
 //--- Methods ---
 public DekiScriptList Add(DekiScriptLiteral value)
 {
     if (value == null)
     {
         throw new ArgumentNullException("value");
     }
     Value.Add(value);
     return(this);
 }
Пример #6
0
 public DekiScriptMap AddAt(string path, DekiScriptLiteral value)
 {
     if (path == null)
     {
         throw new ArgumentNullException("path");
     }
     if (value == null)
     {
         throw new ArgumentNullException("value");
     }
     return(AddAt(path.Split('.'), value));
 }
Пример #7
0
 public bool TryGetValue(string name, out DekiScriptLiteral value)
 {
     if (!_value.TryGetValue(name, out value))
     {
         if (Outer != null)
         {
             return(Outer.TryGetValue(name, out value));
         }
         value = DekiScriptNil.Value;
         return(false);
     }
     return(true);
 }
Пример #8
0
 //--- Constructors ---
 internal DekiScriptUri(XUri value, DekiScriptLiteral args)
 {
     if (value == null)
     {
         throw new ArgumentNullException("value");
     }
     if (args == null)
     {
         throw new ArgumentNullException("args");
     }
     Value     = value;
     Arguments = args;
 }
Пример #9
0
 public bool TryGetValue(DekiScriptLiteral index, out DekiScriptLiteral value)
 {
     if (index == null)
     {
         throw new ArgumentNullException("index");
     }
     if ((index.ScriptType == DekiScriptType.NUM) || (index.ScriptType == DekiScriptType.STR))
     {
         return(TryGetValue(SysUtil.ChangeType <string>(index.NativeValue), out value));
     }
     else
     {
         throw new DekiScriptBadTypeException(Location.None, index.ScriptType, new[] { DekiScriptType.NUM, DekiScriptType.STR });
     }
 }
Пример #10
0
 public DekiScriptLiteral this[DekiScriptLiteral index] {
     get {
         if (index == null)
         {
             return(DekiScriptNil.Value);
         }
         if (index.ScriptType == DekiScriptType.NUM)
         {
             return(this[SysUtil.ChangeType <int>(index.NativeValue)]);
         }
         else
         {
             return(DekiScriptNil.Value);
         }
     }
 }
Пример #11
0
        public DekiScriptMap AddAt(string[] keys, DekiScriptLiteral value, bool ignoreOnError)
        {
            if (ArrayUtil.IsNullOrEmpty(keys))
            {
                throw new ArgumentNullException("keys");
            }
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            // loop over all keys, except last, to get to the last map
            string        key;
            DekiScriptMap current = this;

            for (int i = 0; i < keys.Length - 1; ++i)
            {
                if (keys[i] == null)
                {
                    if (ignoreOnError)
                    {
                        return(this);
                    }
                    throw new ArgumentException(string.Format("keys[{0}] is null", i));
                }
                key = keys[i];
                DekiScriptLiteral next = current[key];
                if (next.ScriptType == DekiScriptType.NIL)
                {
                    next = new DekiScriptMap();
                    current.Add(key, next);
                }
                else if (next.ScriptType != DekiScriptType.MAP)
                {
                    if (ignoreOnError)
                    {
                        return(this);
                    }
                    throw new Exception(string.Format("entry at '{0}' is not a map", string.Join(".", keys, 0, i + 1)));
                }
                current = (DekiScriptMap)next;
            }

            // add new item using the final key
            current.Add(keys[keys.Length - 1], value);
            return(this);
        }
        public static DekiScriptLiteral Constant(XUri value, DekiScriptLiteral[] items)
        {
            DekiScriptLiteral args = DekiScriptNil.Value;

            if (!ArrayUtil.IsNullOrEmpty(items))
            {
                args = List(items);
            }
            else
            {
                // BUGBUGBUG (steveb): we should NOT do execution when building the model!
                if (value.Fragment != null)
                {
                    DekiScriptExpression expr = DekiScriptParser.TryParse(value.Fragment) ?? DekiScriptNil.Value;
                    args = EvalRuntime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, new DekiScriptEnv());
                }
            }
            if ((args.ScriptType != DekiScriptType.NIL) && (args.ScriptType != DekiScriptType.LIST) && (args.ScriptType != DekiScriptType.MAP))
            {
                throw new DekiScriptBadTypeException(Location.None, args.ScriptType, new[] { DekiScriptType.NIL, DekiScriptType.LIST, DekiScriptType.MAP });
            }
            return(new DekiScriptUri(value.WithoutFragment(), args));
        }
Пример #13
0
        public override DekiScriptLiteral Convert(DekiScriptType type)
        {
            switch (type)
            {
            case DekiScriptType.ANY:
            case DekiScriptType.XML:
                return(this);

            case DekiScriptType.BOOL:
            case DekiScriptType.NUM:
            case DekiScriptType.STR:
            case DekiScriptType.URI: {
                string value = AsString();
                if (value != null)
                {
                    DekiScriptLiteral str = Constant(value);
                    return(str.Convert(type));
                }
                break;
            }
            }
            throw new DekiScriptInvalidCastException(Location, ScriptType, type);
        }
Пример #14
0
        //--- Methods ---
        public DekiScriptMap Add(string key, DekiScriptLiteral value)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            // check if colleciton is readonly
            if (_readonly)
            {
                throw new ReadOnlyException(string.Format("map is read-only (attempted to add key '{0}')", key));
            }

            // update value
            if (value == null)
            {
                _value.Remove(key);
            }
            else
            {
                _value[key] = value;
            }
            return(this);
        }
Пример #15
0
        public static DekiScriptLiteral NotEqual(DekiScriptLiteral left, DekiScriptLiteral right)
        {
            if (DekiScriptLiteral.CoerceValuesToSameType(ref left, ref right))
            {
                switch (left.ScriptType)
                {
                case DekiScriptType.NIL:
                    return(DekiScriptBool.False);

                case DekiScriptType.BOOL:
                    return(Constant(left.AsBool() != right.AsBool()));

                case DekiScriptType.NUM:
                    return(Constant(left.AsNumber() != right.AsNumber()));

                case DekiScriptType.STR:
                    return(Constant(!StringUtil.EqualsInvariant(left.AsString(), right.AsString())));

                default:
                    return(Constant(!object.ReferenceEquals(left, right)));
                }
            }
            return(DekiScriptBool.True);
        }
Пример #16
0
        public static DekiScriptLiteral IdentityNotEqual(DekiScriptLiteral left, DekiScriptLiteral right)
        {
            if (left.ScriptType == right.ScriptType)
            {
                switch (left.ScriptType)
                {
                case DekiScriptType.NIL:
                    return(DekiScriptBool.False);

                case DekiScriptType.BOOL:
                    return(Constant(left.AsBool() != right.AsBool()));

                case DekiScriptType.NUM:
                    return(Constant(left.AsNumber() != right.AsNumber()));

                case DekiScriptType.STR:
                    return(Constant(!StringUtil.EqualsInvariant(left.AsString(), right.AsString())));

                default:
                    return(Constant(!ReferenceEquals(left, right)));
                }
            }
            return(DekiScriptBool.True);
        }
Пример #17
0
        private void AddText(XmlNode context, DekiScriptLiteral literal) {
            if(context == null) {
                ConvertStateToHtml(null);
            }

            // TODO (steveb): this is just plain retarded; why do we need to distinguish between string and non-string?!?

            if(literal is DekiScriptString) {
                (context ?? _body).AppendChild(_document.CreateTextNode(((DekiScriptString)literal).Value));
            } else {
                (context ?? _body).AppendChild(_document.CreateTextNode(literal.ToString()));
            }
        }
Пример #18
0
 //--- Methods ---
 public DekiScriptLiteral Convert(DekiScriptLiteral value) {
     try {
         return value.Convert(ScriptType);
     } catch(DekiScriptInvalidCastException) {
         throw new DekiScriptInvalidParameterCastException(Location.None, this, value.ScriptType);
     }
 }
Пример #19
0
        public Range Push(DekiScriptLiteral literal) {
            if(literal.IsNil) {
                return Range.Empty;
            }

            // append element
            int start = _buffer.Count;
            CheckBufferLimits();
            _buffer.Add(literal);
            return new Range(start, _buffer.Count);
        }
Пример #20
0
 internal void ReplaceNodeWithValue(XmlNode node, DekiScriptLiteral value) {
     XmlNode parent = node.ParentNode;
     InsertValueBeforeNode(parent, node, value);
     parent.RemoveChild(node);
 }
Пример #21
0
        public virtual DekiScriptLiteral Invoke(Location location, XUri uri, DekiScriptLiteral args, DekiScriptEnv env) {
            var sw = Stopwatch.StartNew();
            DekiScriptInvocationTargetDescriptor descriptor;
            var target = _functions.TryGetValue(uri, out descriptor) ? descriptor.Target : FindTarget(uri);
            try {

                // invoke function directly
                return target.Invoke(this, args);
            } catch(Exception e) {
                throw UnwrapAsyncException(uri, e).Rethrow();
            } finally {
                sw.Stop();
                bool property = (uri.LastSegment ?? string.Empty).StartsWithInvariant("$");
                env.AddFunctionProfile(location, (descriptor != null) ? (property ? "$" : "") + descriptor.Name : uri.ToString(), sw.Elapsed);
            }
        }
Пример #22
0
 //--- Contructors ---
 public DekiScriptParameter(string name, DekiScriptType type, bool optional, string hint) {
     if(string.IsNullOrEmpty(name)) {
         throw new NullReferenceException("name");
     }
     this.Name = name;
     this.ScriptType = type;
     this.Optional = optional;
     this.Hint = hint;
     this.NativeType = typeof(object);
     this.Default = DekiScriptNil.Value;
 }
 //--- Class Methods ---
 public static bool IsProperty(DekiScriptLiteral value) {
     if(value.ScriptType == DekiScriptType.URI) {
         return (((DekiScriptUri)value).Value.LastSegment ?? string.Empty).StartsWithInvariant("$");
     }
     return false;
 }
Пример #24
0
        //--- Class Methods ---
        public static XDoc Include(string path, string section, bool showTitle, int? adjustHeading, DekiScriptLiteral args, int revision, bool followRedirects, bool returnEmptyDocIfNotFound, bool createAnchor) {
            var resources = DekiContext.Current.Resources;

            // retrieve the page requested
            Title titleToInclude = Title.FromUriPath(path);
            PageBE pageToInclude = PageBL.GetPageByTitle(titleToInclude);
            if(followRedirects) {
                pageToInclude = PageBL.ResolveRedirects(pageToInclude);
            }

            // If the page was not found, create a link to the page placeholder
            if(pageToInclude.ID == 0) {
                return returnEmptyDocIfNotFound ? XDoc.Empty : new XDoc("html").Start("body").Start("a").Attr("href", path).Value(titleToInclude.AsUserFriendlyName()).End().End();
            }
            if(!PermissionsBL.IsUserAllowed(DekiContext.Current.User, pageToInclude, Permissions.READ)) {
                return new XDoc("html").Start("body").Value(resources.Localize(DekiResources.RESTRICT_MESSAGE())).End();
            }

            // load old revision of page
            if(revision != 0) {
                PageBL.ResolvePageRev(pageToInclude, revision.ToString());
            }

            // parse the page
            ParserResult result = Parse(pageToInclude, pageToInclude.ContentType, pageToInclude.Language, pageToInclude.GetText(DbUtils.CurrentSession), ParserMode.VIEW, true, -1, args, null);

            // if requested, extract the specified section
            XDoc doc;
            if(section != null) {
                XmlNode startNode, endNode;
                FindSection(result.MainBody, section, out startNode, out endNode);
                XDoc body = ExtractSection(false, startNode, endNode);

                // If the section was not found, create a link to the page whose section is missing
                if(null == startNode) {
                    if(returnEmptyDocIfNotFound) {
                        return XDoc.Empty;
                    }
                    body = body.Start("a").Attr("href", path).Attr("rel", "internal").Value(titleToInclude.AsUserFriendlyName()).End();
                } else if(adjustHeading.HasValue) {

                    // header needs to be adjusted
                    int current;
                    if(int.TryParse(startNode.LocalName.Substring(1), out current)) {
                        if(showTitle) {
                            body.AddNodesInFront(new XDoc("body").Add(result.MainBody[startNode]));
                        }
                        RelabelHeadings(body, adjustHeading.Value - current);
                    }
                }
                doc = new XDoc("html").Add(result.Head).Add(body).Add(result.Tail);
            } else {
                doc = new XDoc("html").Add(result.Head);

                // check if header needs to be adjusted
                if(adjustHeading.HasValue) {
                    if(showTitle) {
                        result.MainBody.AddNodesInFront(new XDoc("body").Elem("h1", pageToInclude.CustomTitle ?? pageToInclude.Title.AsUserFriendlyName()));
                    }
                    RelabelHeadings(result.MainBody, adjustHeading.Value - 1);
                }

                // add optional anchor
                if(createAnchor) {
                    result.MainBody.AddNodesInFront(new XDoc("body").Start("span").Attr("pagelink", DekiContext.Current.UiUri.AtPath(pageToInclude.Title.AsUiUriPath())).Attr("id", "s" + pageToInclude.ID).End());
                }
                doc.AddAll(result.Bodies).Add(result.Tail);
            }

            // replace all <span id="page.toc" /> place holders
            if(!pageToInclude.Title.IsTemplate) {
                var toc = ProcessPageHeadings(doc);
                XDoc tocDiv = null;
                foreach(XDoc pageToc in doc["body//span[@id='page.toc']"]) {
                    if(tocDiv == null) {
                        tocDiv = new XDoc("div").Attr("class", "wiki-toc").AddNodes(toc);
                    }
                    pageToc.Replace(TruncateTocDepth(tocDiv, pageToc["@depth"].AsInt));
                }
            }
            return doc;
        }
Пример #25
0
        public static ParserResult Parse(PageBE page, string contentType, string language, string content, ParserMode mode, bool isInclude, int section, DekiScriptLiteral args, Title relToTitle) {
            XDoc xhtml = CreateParserDocument(page, contentType, language, content, mode);

            // check if we're interested only in a given section
            if(0 < section) {
                XDoc mainBody = xhtml[MAIN_BODY_XPATH];
                XmlNode startNode, endNode;
                FindSection(mainBody, section, out startNode, out endNode);
                mainBody.Replace(ExtractSection(true, startNode, endNode));
            }

            // process page contents
            ParserResult result = Parse(page, xhtml, mode, isInclude, args, relToTitle);

            // check if we need to append extra elements to document for editing
            if(mode == ParserMode.EDIT) {
                XDoc body = result.MainBody;
                if(!body.IsEmpty) {
                    XmlNode last = body.AsXmlNode.LastChild;

                    // check if last node is a <table> or <pre> element
                    if(last != null) {
                        if(last.NodeType == XmlNodeType.Element) {
                            if(last.LocalName.EqualsInvariant("table") || last.LocalName.EqualsInvariant("pre")) {

                                // add a <br /> element
                                body.Elem("br");
                            } else if(last.LocalName.EqualsInvariant("h1") ||
                                last.LocalName.EqualsInvariant("h2") ||
                                last.LocalName.EqualsInvariant("h3") ||
                                last.LocalName.EqualsInvariant("h4") ||
                                last.LocalName.EqualsInvariant("h5") ||
                                last.LocalName.EqualsInvariant("h6")
                            ) {

                                // add a <br /> element
                                body.Elem("br");
                            }
                        }
                    } else {

                        // add a <br /> element
                        body.Elem("br");
                    }
                }
            } else if(((mode == ParserMode.VIEW) || (mode == ParserMode.VIEW_NO_EXECUTE)) && isInclude) {
                XDoc body = result.MainBody;
                XmlNode para = null;
                foreach(XmlNode node in body.AsXmlNode.ChildNodes) {
                    if((node.NodeType == XmlNodeType.Element) && node.Name.EqualsInvariant("p") && (para == null)) {

                        // capture the first <p> node
                        para = node;
                        continue;
                    } else if(node.NodeType == XmlNodeType.Whitespace) {

                        // found a whitespace node; ignore it
                        continue;
                    } else if((node.NodeType == XmlNodeType.Text) && string.IsNullOrEmpty(node.Value.Trim())) {

                        // found an empty text node; ignore it
                        continue;
                    }

                    // found other content; don't strip anything
                    para = null;
                    break;
                }

                // check if a single paragraph was found; if so, remove the <p> tags, but keep the contents
                if(para != null) {
                    body.RemoveNodes();
                    body.AddNodes(body[para]);
                }
            }
            return result;
        }
Пример #26
0
        private static ParserResult Parse(PageBE page, XDoc result, ParserMode mode, bool isInclude, DekiScriptLiteral args, Title relToTitle) {
            Title redirectsToTitle = null;
            XUri redirectsToUri = null;
            bool hasScriptContent = false;
            List<Title> outboundLinks = null;
            List<Title> templates = null;
            List<string> tags = null;
            XDoc tableOfContents = null;
            if(ParserMode.RAW != mode) {

                // lookup the current parse state 
                ParserState parseState = GetParseState();
                string parseStateKey = GetParserCacheKey(page, mode);
                XDoc cachedResult = null;

                // if this page is included whithin another, check the state of the parse cache
                if(isInclude && parseState.ProcessedPages.TryGetValue(parseStateKey, out cachedResult)) {
                    if(null == cachedResult) {
                        if(mode == ParserMode.VIEW) {
                            mode = ParserMode.VIEW_NO_EXECUTE;
                            parseStateKey = GetParserCacheKey(page, mode);
                        } else {
                            throw new DekiXmlParserInfinitePageInclusionInvalidScriptException();
                        }
                    } else {
                        result = cachedResult;
                    }
                }
                if(null == cachedResult) {

                    // init environment for page processing
                    PageBE basePage = page;
                    if(page.Title.IsTemplate) {
                        for(int i = parseState.ProcessingStack.Count - 1; i >= 0; --i) {

                            // select the first non-template page
                            if(!parseState.ProcessingStack[i].Title.IsTemplate) {
                                basePage = parseState.ProcessingStack[i];
                                break;
                            }
                        }
                    }

                    // update the parse state to indicate the page is in the process of being parsed
                    parseState.ProcessedPages[parseStateKey] = null;
                    parseState.ProcessingStack.Add(page);

                    // set current page in context
                    DreamContext context = DreamContext.Current;
                    PageBE prevBasePage = context.GetState<PageBE>("CurrentPage");
                    CultureInfo prevCulture = context.Culture;
                    context.SetState("CurrentPage", basePage);
                    context.Culture = HttpUtil.GetCultureInfoFromHeader(basePage.Language, context.Culture);

                    // resolve the redirect if this page is marked as a redirect or new content is being processed
                    if(page.IsRedirect || (ParserMode.SAVE == mode)) {
                        object redirect = ProcessRedirect(result, mode);
                        redirectsToTitle = redirect as Title;
                        redirectsToUri = redirect as XUri;
                    }
                    if((null != redirectsToTitle) || (null != redirectsToUri)) {
                        outboundLinks = new List<Title>();
                        if(null != redirectsToTitle) {
                            outboundLinks.Add(redirectsToTitle);
                        }
                    } else {

                        // check 'content-type' to determine if we need to convert
                        if(DekiMimeType.DEKI_TEXT.EqualsInvariant(result["content/@type"].Contents)) {
                            WikiConverter_TextToXml.Convert(result);
                            result["content/@type"].ReplaceValue(DekiMimeType.DEKI_XML0702);
                        }
                        ProcessPage(page, result, mode, isInclude, basePage, args, relToTitle, out tableOfContents, out hasScriptContent, out outboundLinks, out templates, out tags);
                    }

                    // restore previous page context
                    context.SetState("CurrentPage", prevBasePage);
                    context.Culture = prevCulture;

                    // update the parse state to indicate the page as been successfully parsed
                    if(!page.Title.IsTemplate) {
                        parseState.ProcessedPages[parseStateKey] = result;
                    } else {
                        parseState.ProcessedPages.Remove(parseStateKey);
                    }
                    parseState.ProcessingStack.RemoveAt(parseState.ProcessingStack.Count - 1);
                }
            }

            // add table of contents
            XDoc content = result["content"];
            if((tableOfContents != null) && content["body[@target='toc']"].IsEmpty) {
                content.Start("body").Attr("target", "toc").AddNodes(tableOfContents);
            }

            // get content type
            string contentType = result["content/@type"].Contents;
            result["content/@type"].Remove();

            // extract the parser results
            return new ParserResult(
                result["content"],
                contentType,
                redirectsToTitle,
                redirectsToUri,
                hasScriptContent,
                outboundLinks,
                templates,
                tags
            );
        }
Пример #27
0
 public DekiScriptMap AddAt(string[] keys, DekiScriptLiteral value)
 {
     return(AddAt(keys, value, true));
 }
Пример #28
0
        private static void ProcessPage(PageBE page, XDoc content, ParserMode mode, bool isInclude, PageBE basePage, DekiScriptLiteral args, Title relToTitle, out XDoc tableOfContents, out bool hasScriptContent, out List<Title> outboundLinks, out List<Title> templates, out List<string> tags) {
            DekiXmlParser parser = new DekiXmlParser(page, content, mode, isInclude, basePage, args, relToTitle);

            // 1) process structure of document
            parser.ProcessStructure();
            tags = parser.ProcessTagsToBeInserted();

            // 2) process edit sections
            parser.ProcessEditSections();

            // 3) process links to attachments
            parser.ProcessAttachmentLinks();

            // 4) process script content (variables and functions)
            hasScriptContent = parser.ProcessScripts();

            // 5) process free-form external links
            parser.ProcessFreeLinks();

            // 6) process internal/external links
            parser.ProcessLinks(out outboundLinks, out templates);

            // 7) process images
            parser.ProcessImages();

            // 8) auto-number links
            parser.AutoNumberLinks();

            // 9) process nowiki tags
            parser.ProcessNoWiki();

            // 10) process words (banned & highlighted)
            parser.ProcessWords();

            // 11) process headings
            tableOfContents = parser.ProcessHeadings();

            // adjust content type
            if(mode == ParserMode.SAVE) {
                content["content/@type"].ReplaceValue(DekiMimeType.DEKI_XML0805);
            } else if(mode == ParserMode.EDIT) {
                content["content/@type"].ReplaceValue(DekiMimeType.DEKI_TEXT);
            } else if((mode == ParserMode.VIEW_NO_EXECUTE) || (mode == ParserMode.VIEW)) {
                content["content/@type"].ReplaceValue(DekiMimeType.HTML_TEXT);
            }
        }
 //--- Constructors ---
 public DekiScriptReturnException(Location location, DekiScriptLiteral value) : base(location, "Unhandled 'return' statement") {
     if(value == null) {
         throw new ArgumentNullException("value");
     }
     this.Value = value;
 }
 public virtual DekiScriptLiteral EvaluateProperty(Location location, DekiScriptLiteral value, DekiScriptEnv env) {
     if(IsProperty(value)) {
         DekiScriptUri uri = (DekiScriptUri)value;
         try {
             value = Invoke(uri.Value, uri.Arguments.IsNil ? _emptyList : uri.Arguments, env);
         } catch(DekiScriptFatalException) {
             throw;
         } catch(Exception e) {
             var descriptor = ResolveRegisteredFunctionUri(uri.Value);
             throw new DekiScriptInvokeException(location, uri.Value, (descriptor != null) ? descriptor.Name : uri.Value.ToString(), e);
         }
     }
     return value;
 }
Пример #31
0
 //--- Constructors ---
 private DekiXmlParser(PageBE page, XDoc content, ParserMode mode, bool isInclude, PageBE basePage, DekiScriptLiteral args, Title relToTitle) {
     this._page = page;
     this._content = content;
     this._mode = mode;
     this._isInclude = isInclude;
     this._basePage = basePage;
     this._args = args;
     this._relToTitle = relToTitle;
 }
        public virtual DekiScriptLiteral Invoke(XUri uri, DekiScriptLiteral args, DekiScriptEnv env) {
            DekiScriptInvocationTargetDescriptor descriptor;
            var target = _functions.TryGetValue(uri, out descriptor) ? descriptor.Target : FindTarget(uri);

            // invoke function directly
            try {
                return target.Invoke(this, args);
            } catch(Exception e) {
                throw UnwrapAsyncException(uri, e).Rethrow();
            }
        }
 public static XDoc DekiScriptToXmlRpc(string function, DekiScriptLiteral arguments) {
     XDoc xdoc = new XDoc("methodCall");
     xdoc.Elem("methodName", function);
     if(arguments.ScriptType.Equals(DekiScriptType.LIST)) {
         XmlRpcLiteralRecurse(xdoc, arguments, true);
     } else {
         xdoc.Start("params").Start("param");
         XmlRpcLiteralRecurse(xdoc, arguments, false);
         xdoc.End().End();
     }
     return xdoc;
 }
Пример #34
0
 public DekiScriptParameter(string name, DekiScriptType type, bool optional, string hint, Type nativeType, DekiScriptLiteral @default) {
     if(string.IsNullOrEmpty(name)) {
         throw new NullReferenceException("name");
     }
     if(nativeType == null) {
         throw new NullReferenceException("nativeType");
     }
     if(@default == null) {
         throw new NullReferenceException("default");
     }
     this.Name = name;
     this.ScriptType = type;
     this.Optional = optional;
     this.Hint = hint;
     this.NativeType = nativeType;
     this.Default = @default;
 }
Пример #35
0
        public static bool CoerceValuesToSameType(ref DekiScriptLiteral left, ref DekiScriptLiteral right)
        {
            // weed out the trivial case where the literals cannot be converted
            switch (left.ScriptType)
            {
            case DekiScriptType.NIL:
            case DekiScriptType.URI:
            case DekiScriptType.LIST:
            case DekiScriptType.MAP:
            case DekiScriptType.XML:

                // we can't convert complex literals; only succeed if the types match
                return(left.ScriptType == right.ScriptType);
            }
            switch (right.ScriptType)
            {
            case DekiScriptType.NIL:
            case DekiScriptType.URI:
            case DekiScriptType.LIST:
            case DekiScriptType.MAP:
            case DekiScriptType.XML:

                // we can't convert complex literals; only succeed if the types match
                return(left.ScriptType == right.ScriptType);
            }

            // now determine what needs to be converted
            switch (left.ScriptType)
            {
            case DekiScriptType.BOOL:
                switch (right.ScriptType)
                {
                case DekiScriptType.BOOL:

                    // nothing to do
                    return(true);

                case DekiScriptType.NUM:

                    // convert left value from bool to number
                    left = Constant(left.AsNumber());
                    return(true);

                case DekiScriptType.STR: {
                    // check if right string can be converted to bool; otherwise convert left bool to string
                    bool?value = right.AsBool();
                    if (value == null)
                    {
                        left = Constant(left.AsString());
                    }
                    else
                    {
                        right = Constant(value);
                    }
                    return(true);
                }
                }
                break;

            case DekiScriptType.NUM:
                switch (right.ScriptType)
                {
                case DekiScriptType.BOOL:

                    // convert right value from bool to number
                    right = Constant(right.AsNumber());
                    return(true);

                case DekiScriptType.NUM:

                    // nothing to do
                    return(true);

                case DekiScriptType.STR: {
                    // check if right string can be converted to number; otherwise convert left number to string
                    double?value = right.AsNumber();
                    if (value == null)
                    {
                        left = Constant(left.AsString());
                    }
                    else
                    {
                        right = Constant(value);
                    }
                    return(true);
                }
                }
                break;

            case DekiScriptType.STR:
                switch (right.ScriptType)
                {
                case DekiScriptType.BOOL: {
                    // check if left string can be converted to bool; otherwise convert right bool to string
                    bool?value = left.AsBool();
                    if (value == null)
                    {
                        right = Constant(right.AsString());
                    }
                    else
                    {
                        left = Constant(value);
                    }
                    return(true);
                }

                case DekiScriptType.NUM: {
                    // check if left string can be converted to number; otherwise convert right number to string
                    double?value = left.AsNumber();
                    if (value == null)
                    {
                        right = Constant(right.AsString());
                    }
                    else
                    {
                        left = Constant(value);
                    }
                    return(true);
                }

                case DekiScriptType.STR:

                    // nothing to do
                    return(true);
                }
                break;
            }
            throw new InvalidOperationException(string.Format("invalid value pair: left = {0}, right = {1}", left.ScriptTypeName, right.ScriptTypeName));
        }
Пример #36
0
 public virtual void LogExceptionInOutput(DekiScriptLiteral error) {
     Log.Info("exception in dekiscript output: " +  DekiScriptLibrary.JsonFormat(error.NativeValue));
 }
Пример #37
0
        public static bool CoerceValuesToSameType(ref DekiScriptLiteral left, ref DekiScriptLiteral right) {

            // weed out the trivial case where the literals cannot be converted
            switch(left.ScriptType) {
            case DekiScriptType.NIL:
            case DekiScriptType.URI:
            case DekiScriptType.LIST:
            case DekiScriptType.MAP:
            case DekiScriptType.XML:

                // we can't convert complex literals; only succeed if the types match
                return left.ScriptType == right.ScriptType;
            }
            switch(right.ScriptType) {
            case DekiScriptType.NIL:
            case DekiScriptType.URI:
            case DekiScriptType.LIST:
            case DekiScriptType.MAP:
            case DekiScriptType.XML:

                // we can't convert complex literals; only succeed if the types match
                return left.ScriptType == right.ScriptType;
            }

            // now determine what needs to be converted
            switch(left.ScriptType) {
            case DekiScriptType.BOOL:
                switch(right.ScriptType) {
                case DekiScriptType.BOOL:

                    // nothing to do
                    return true;
                case DekiScriptType.NUM:

                    // convert left value from bool to number
                    left = Constant(left.AsNumber());
                    return true;
                case DekiScriptType.STR: {

                    // check if right string can be converted to bool; otherwise convert left bool to string
                    bool? value = right.AsBool();
                    if(value == null) {
                        left = Constant(left.AsString());
                    } else {
                        right = Constant(value);
                    }
                    return true;
                }
                }
                break;
            case DekiScriptType.NUM:
                switch(right.ScriptType) {
                case DekiScriptType.BOOL:

                    // convert right value from bool to number
                    right = Constant(right.AsNumber());
                    return true;
                case DekiScriptType.NUM:

                    // nothing to do
                    return true;
                case DekiScriptType.STR: {

                    // check if right string can be converted to number; otherwise convert left number to string
                    double? value = right.AsNumber();
                    if(value == null) {
                        left = Constant(left.AsString());
                    } else {
                        right = Constant(value);
                    }
                    return true;
                }
                }
                break;
            case DekiScriptType.STR:
                switch(right.ScriptType) {
                case DekiScriptType.BOOL: {

                    // check if left string can be converted to bool; otherwise convert right bool to string
                    bool? value = left.AsBool();
                    if(value == null) {
                        right = Constant(right.AsString());
                    } else {
                        left = Constant(value);
                    }
                    return true;
                }
                case DekiScriptType.NUM: {

                    // check if left string can be converted to number; otherwise convert right number to string
                    double? value = left.AsNumber();
                    if(value == null) {
                        right = Constant(right.AsString());
                    } else {
                        left = Constant(value);
                    }
                    return true;
                }
                case DekiScriptType.STR:

                    // nothing to do
                    return true;
                }
                break;
            }
            throw new InvalidOperationException(string.Format("invalid value pair: left = {0}, right = {1}", left.ScriptTypeName, right.ScriptTypeName));
        }
 public DekiScriptOutputBuffer.Range Push(DekiScriptLiteral value) {
     return Buffer.Push(value);
 }
Пример #39
0
        internal void InsertValueBeforeNode(XmlNode parent, XmlNode reference, DekiScriptLiteral value) {
            if((value is DekiScriptXml) || (value is DekiScriptUri)) {
                XDoc xml = value.AsEmbeddableXml(Mode == DekiScriptEvalMode.EvaluateSafeMode);
                if(xml.HasName("html")) {

                    // TODO (steveb): merge XML namespaces

                    // merge <head> and <tail> sections
                    AddHeadElements(xml);
                    AddTailElements(xml);

                    // loop over body elements in response
                    foreach(XDoc body in xml["body"]) {
                        string target = body["@target"].AsText;
                        string conflict = body["@conflict"].AsText ?? "ignore";

                        // check if the main body is targeted or something else
                        if(string.IsNullOrEmpty(target)) {

                            // append body nodes
                            foreach(XmlNode node in body.AsXmlNode.ChildNodes) {
                                parent.InsertBefore(parent.OwnerDocument.ImportNode(node, true), reference);
                            }
                        } else {

                            // check if the targeted body already exists
                            if(Bodies.ContainsKey(target) && !StringUtil.EqualsInvariant(conflict, "replace")) {
                                if(StringUtil.EqualsInvariant(conflict, "append")) {

                                    // append nodes to existing body
                                    Bodies[target].Add(body.AsXmlNode);
                                }
                            } else {

                                // create a new body element
                                List<XmlNode> list = new List<XmlNode>();
                                list.Add(body.AsXmlNode);
                                Bodies[target] = list;
                            }
                        }
                    }
                } else if(!xml.IsEmpty) {

                    // replace the current node with the entire document
                    parent.InsertBefore(parent.OwnerDocument.ImportNode(xml.AsXmlNode, true), reference);
                }
            } else if(value is DekiScriptComplexLiteral) {

                // append text respresentation of value
                parent.InsertBefore(CreateTextNode(value.ToString()), reference);
            } else {

                // append value cast to text
                string text = value.AsString();
                if(!string.IsNullOrEmpty(text)) {
                    parent.InsertBefore(CreateTextNode(text), reference);
                }
            }
        }