Wrapper over tab stops utility in the Emmet engine. Can be used to prepare expanded abbreviations to be inserted into the editor and get information about tab stops.
예제 #1
0
        /// <summary>
        /// Looks for tab stops in the specified content and returns a processed version with expanded
        /// placeholders and tab stops found.
        /// </summary>
        /// <param name="engine">V8 instance with Emmet engine compiled in it.</param>
        /// <param name="content">Expanded abbreviation content.</param>
        /// <exception cref="Exception{EmmetEngineExceptionArgs}">
        /// Indicates that Emmet engine has failed to parse the specified content.
        /// </exception>
        public static TabStopsParser ParseContent(V8Engine engine, string content)
        {
            ObjectHandle tabStopsUtil  = engine.DynamicGlobalObject.window.emmet.tabStops;
            Handle       extractResult = tabStopsUtil.Call("extract", null, engine.CreateValue(content));

            if (extractResult.IsError)
            {
                var ex = new EmmetEngineExceptionArgs(
                    "Error while trying to extract tab stops.",
                    extractResult);
                throw new Exception <EmmetEngineExceptionArgs>(ex);
            }

            TabStopsParser retVal      = new TabStopsParser();
            ObjectHandle   tabStopsObj = (ObjectHandle)extractResult;

            retVal.Content = tabStopsObj.GetProperty(@"text").AsString;
            ObjectHandle tabStopsList = tabStopsObj.GetProperty(@"tabstops");

            // Tab stops should be added before modifying document so that editor can track their position.
            int tabStopsCount = tabStopsList.ArrayLength;

            if (tabStopsCount > 0)
            {
                retVal.TabStops      = new Range[tabStopsCount];
                retVal.TabStopGroups = new int[tabStopsCount];

                for (int i = 0; i < tabStopsCount; i++)
                {
                    ObjectHandle tabStopObj = tabStopsList.GetProperty(i.ToString());
                    int          start      = tabStopObj.GetProperty("start").AsInt32;
                    int          end        = tabStopObj.GetProperty("end").AsInt32;
                    int          group      = tabStopObj.GetProperty("group").AsInt32;

                    retVal.TabStops[i]      = new Range(start, end);
                    retVal.TabStopGroups[i] = group;
                }
            }

            return(retVal);
        }
예제 #2
0
        /// <summary>
        /// Looks for tab stops in the specified content and returns a processed version with expanded
        /// placeholders and tab stops found.
        /// </summary>
        /// <param name="content">Expanded abbreviation content.</param>
        /// <param name="offset">(Optional) The offset of the content in containing document.</param>
        public static TabStopsParser ParseContent(string content, int offset = 0)
        {
            var tabStops      = new List <Span>(5);
            int tabStopOffset = 0;

            var retVal = new TabStopsParser();

            retVal.Content = Parser.Replace(
                content,
                (Match m) =>
            {
                string replacement = m.Groups[1]?.Value ?? string.Empty;
                tabStops.Add(new Span(offset + m.Index - tabStopOffset, replacement.Length));
                tabStopOffset += m.Length - replacement.Length;

                return(replacement);
            });
            retVal.TabStops = tabStops.ToArray();

            return(retVal);
        }
예제 #3
0
        /// <summary>
        /// Looks for tab stops in the specified content and returns a processed version with expanded
        /// placeholders and tab stops found.
        /// </summary>
        /// <param name="engine">V8 instance with Emmet engine compiled in it.</param>
        /// <param name="content">Expanded abbreviation content.</param>
        /// <exception cref="Exception{EmmetEngineExceptionArgs}">
        /// Indicates that Emmet engine has failed to parse the specified content.
        /// </exception>
        public static TabStopsParser ParseContent(V8Engine engine, string content)
        {
            ObjectHandle tabStopsUtil = engine.DynamicGlobalObject.window.emmet.tabStops;
            Handle extractResult = tabStopsUtil.Call("extract", null, engine.CreateValue(content));

            if (extractResult.IsError)
            {
                var ex = new EmmetEngineExceptionArgs(
                    "Error while trying to extract tab stops.",
                    extractResult);
                throw new Exception<EmmetEngineExceptionArgs>(ex);
            }

            TabStopsParser retVal = new TabStopsParser();
            ObjectHandle tabStopsObj = (ObjectHandle)extractResult;
            retVal.Content = tabStopsObj.GetProperty(@"text").AsString;
            ObjectHandle tabStopsList = tabStopsObj.GetProperty(@"tabstops");

            // Tab stops should be added before modifying document so that editor can track their position.
            int tabStopsCount = tabStopsList.ArrayLength;

            if (tabStopsCount > 0)
            {
                retVal.TabStops = new Range[tabStopsCount];
                retVal.TabStopGroups = new int[tabStopsCount];

                for (int i = 0; i < tabStopsCount; i++)
                {
                    ObjectHandle tabStopObj = tabStopsList.GetProperty(i.ToString());
                    int start = tabStopObj.GetProperty("start").AsInt32;
                    int end = tabStopObj.GetProperty("end").AsInt32;
                    int group = tabStopObj.GetProperty("group").AsInt32;

                    retVal.TabStops[i] = new Range(start, end);
                    retVal.TabStopGroups[i] = group;
                }
            }

            return retVal;
        }
예제 #4
0
        /// <summary>
        /// JavaScript callback. Replace editor's content or it's part (from <code>start</code> to
        /// <code>end</code> index). If <code>value</code> contains <code>caret_placeholder</code>, the editor
        /// will put caret into this position. If you skip <code>start</code> and <code>end</code> arguments,
        /// the whole target's content will be replaced with <code>value</code>.
        /// If you pass <code>start</code> argument only, the <code>value</code> will be placed at
        /// <code>start</code> string index of current content.
        /// If you pass <code>start</code> and <code>end</code> arguments, the corresponding substring of
        /// current target's content will be replaced with <code>value</code>.
        /// </summary>
        public InternalHandle ReplaceContent(
            V8Engine engine,
            bool isConstructCall,
            InternalHandle self,
            params InternalHandle[] args)
        {
            string rawContent    = args[0].AsString;
            int    regionStart   = args.Length > 1 ? args[1].AsInt32 : -1;
            int    regionLength  = args.Length > 2 ? args[2].AsInt32 - regionStart : 0;
            bool   indentContent = args.Length == 4 ? args[3].AsBoolean : true;

            this.Trace($"Received new content for the editor: {rawContent}");

            // Extract tab stops placeholders from the specified content.
            var tabStops = TabStopsParser.ParseContent(engine, rawContent);

            _editor.ReplaceContentRange(tabStops.Content, regionStart, regionStart + regionLength);

            if (null != tabStops.TabStops)
            {
                Range[] tabStopRanges = tabStops.TabStops;

                // Tab stop offsets are relative to the newly generated content ranges, we need to convert
                // them to the document-wide offsets.
                if (regionStart > 0)
                {
                    tabStopRanges = tabStopRanges.Select(
                        item => new Range(item.Start + regionStart, item.End + regionStart)).ToArray();
                }

                _editor.TrackTabStops(tabStopRanges, tabStops.TabStopGroups);
            }

            if (indentContent)
            {
                _editor.FormatRegion(regionStart, regionStart + tabStops.Content.Length);
            }

            return(engine.CreateValue(true));
        }