public static void AddChangesToBounds(
            PreprocessedTextLocationMap map,
            List<PreprocessingTextChange> changes,
            PreprocessedData data,
            PreprocessedTextType type)
        {
            if (data == null)
            {
                return;
            }

            foreach (var change in changes)
            {
                if (change.RemoveCharsCount == 0)
                {
                    continue;
                }

                var start = change.Index;
                var end = change.Index + change.RemoveCharsCount - 1;

                if(map != null)
                {
                    start = map.GetOriginalPosition(start, PositionRounding.Up);
                    end = map.GetOriginalPosition(end, PositionRounding.Down);
                }

                data.PreprocessedTextBounds.Add(
                    new PreprocessedTextBound(
                        type, start, end));
            }
        }
        public string ParseExcerpts(string text, TransformationData data, PreprocessedTextLocationMap map)
        {
            var excerptInfos = new Dictionary<string, ExcerptInfo>();

            text = ProcessExcerpt(ExcerptBlock, text, data, excerptInfos, map);
            text = ProcessExcerpt(ExcerptInline, text, data, excerptInfos, map);

            foreach (var excerptInfo in excerptInfos)
            {
                AddExcerpt(data, excerptInfo.Value, excerptInfo.Key);
            }

            AddExcerpt(data, new ExcerptInfo(map.GetOriginalPosition(0, PositionRounding.Down), 0, text), "");

            return text;
        }
Esempio n. 3
0
        public void AugmentCompletionSession(SnapshotSpan span, IList <CompletionSet> completionSets)
        {
            var text = span.GetText();

            var map = new PreprocessedTextLocationMap();

            text = VariableManager.CutoutVariableInclusions(text, map);

            var match = LinkStartPattern.Match(text);

            if (!match.Success)
            {
                return;
            }

            var suggestionMatchGroup = match.Groups["suggestion"];
            var pathMatchGroup       = match.Groups["path"];

            List <PathElement> list;

            if (match.Groups["link"].Success)
            {
                var isImageLink = match.Groups["image"].Success;

                list =
                    PathCompletionHelper.GetSuggestionList(
                        UDNDocRunningTableMonitor.CurrentUDNDocView.ParsingResultsCache.Results.Document,
                        pathMatchGroup.Value,
                        (!isImageLink ? PathElementType.Attachment : 0) | PathElementType.Folder
                        | ((string.IsNullOrWhiteSpace(pathMatchGroup.Value) && !isImageLink)
                               ? PathElementType.Bookmark
                               : 0) | (isImageLink ? PathElementType.Image : 0));
            }
            else if (match.Groups["include"].Success)
            {
                if (pathMatchGroup.Length == 0)
                {
                    if (match.Groups["hash"].Success)
                    {
                        list = GetLocalSuggestions(PathElementType.Excerpt);
                    }
                    else
                    {
                        list = GetLocalSuggestions(PathElementType.Excerpt)
                               .Select(e => new PathElement("#" + e.Text, e.Type))
                               .ToList();

                        list.AddRange(GetRootFolders());
                    }
                }
                else
                {
                    list =
                        PathCompletionHelper.GetSuggestionList(
                            UDNDocRunningTableMonitor.CurrentUDNDocView.CurrentEMDocument,
                            "%ROOT%/" + pathMatchGroup.Value,
                            match.Groups["hash"].Success ? PathElementType.Excerpt : PathElementType.Folder);
                }
            }
            else if (match.Groups["variable"].Success)
            {
                if (pathMatchGroup.Length == 0)
                {
                    list = GetRootFolders();
                    list.AddRange(GetLocalSuggestions(PathElementType.Variable));
                }
                else
                {
                    var types = match.Groups["colon"].Success ? PathElementType.Variable : PathElementType.Folder;
                    var path  = "%ROOT%/" + pathMatchGroup.Value.Substring(0, pathMatchGroup.Length - 1);

                    list = PathCompletionHelper.GetSuggestionList(
                        UDNDocRunningTableMonitor.CurrentUDNDocView.CurrentEMDocument, path, types);
                }
            }
            else
            {
                throw new InvalidOperationException("Should not happen!");
            }

            try
            {
                var trackingSpan = span.Snapshot.CreateTrackingSpan(
                    span.Start + map.GetOriginalPosition(suggestionMatchGroup.Index, PositionRounding.None),
                    suggestionMatchGroup.Length,
                    SpanTrackingMode.EdgeInclusive);

                completionSets.Add(
                    new CompletionSet(
                        "AutoCompletion",
                        "AutoCompletion",
                        trackingSpan,
                        CompletionCreator.SortAndCreateCompletions(list),
                        null));
            }
            catch (UnableToDetectOriginalPositionException)
            {
                // ignore and don't show completions
            }
        }
Esempio n. 4
0
        private static List <TableRowInformation> GetHeaders(EMDocument doc, EMElementOrigin origin, EMElement parent, TransformationData data, int headerOffset, string tableHeader, out bool useRowHeader)
        {
            // Add headers
            // May be multiple lines, may have columns spanning
            // May also have no header if we are intending the 1st column to be the header

            var map = new PreprocessedTextLocationMap();

            tableHeader = RemoveTrailingWhitespaceAndNewLines(tableHeader, map);

            List <TableRowInformation> templateHeaderRows = null;

            useRowHeader = true;

            if (!String.IsNullOrWhiteSpace(tableHeader))
            {
                templateHeaderRows = new List <TableRowInformation>();

                var headerRowOffset = 0;

                var headerRows = Regex.Split(tableHeader, @"\n");
                foreach (var headerRow in headerRows)
                {
                    var count = 0;

                    var headerColumns = Regex.Matches(headerRow, @"[ ]?([^\|]+)[ ]?([\|]*)");
                    var row           = new TableRowInformation();

                    foreach (Match headerColumn in headerColumns)
                    {
                        var cellGroup        = headerColumn.Groups[1];
                        var columnSpanLength = 1;

                        if (Regex.Match(headerColumn.Groups[2].Value, @"(\|{2,})").Success)
                        {
                            columnSpanLength = Regex.Match(headerColumn.Groups[2].Value, @"(\|{2,})").Length;
                        }

                        var cell = new TableCellInformation(doc, new EMElementOrigin(headerOffset + map.GetOriginalPosition(headerRowOffset + cellGroup.Index, PositionRounding.Down), cellGroup.Value), parent, data, columnSpanLength, null, true);

                        if (count == 0)
                        {
                            useRowHeader = !Regex.Match(cell.ToString(), @"(\S)").Success;
                        }

                        count++;

                        row.Cells.Add(cell);
                    }

                    headerRowOffset += headerRow.Length + 1;
                    templateHeaderRows.Add(row);
                }
            }

            return(templateHeaderRows);
        }
Esempio n. 5
0
        private static List <TableRowInformation> GetRows(
            EMElement parent,
            TransformationData data,
            int tableDataOffset,
            string tableData,
            string[] alignments,
            bool useRowHeader,
            bool hasHeader)
        {
            // Add body data
            var tableRows = new List <TableRowInformation>();

            var map = new PreprocessedTextLocationMap();

            tableData = RemoveTrailingWhitespaceAndNewLines(tableData, map);

            var dataRows = Regex.Split(tableData, @"\n");

            var rowOffset = 0;

            for (var i = 0; i < dataRows.Count(); ++i)
            {
                var dataRow = dataRows[i];

                // Parse table into List of List of CellInformation
                var count = 0;

                var dataColumns = Regex.Matches(dataRow, @"([^\|]+)([\|]*)");

                var tableRow = new TableRowInformation();

                // Check to see if someone has left an empty row incorrectly formatted, which we can fix.
                if (dataColumns.Count == 0)
                {
                    var fixedDataRow = dataRow;
                    for (var j = dataRow.Length; j < alignments.Length + 1; ++j)
                    {
                        fixedDataRow += '|';
                    }
                    fixedDataRow = fixedDataRow.Insert(1, " ");

                    dataColumns = Regex.Matches(fixedDataRow, @"([^\|]+)([\|]*)");
                }

                foreach (Match dataColumn in dataColumns)
                {
                    int addToOffset;
                    var cell = Normalizer.LeadingWhitespaceRemove(dataColumn.Groups[1].Value, out addToOffset);
                    cell = Normalizer.TrailingWhitespaceRemove(cell);

                    var columnSpanLength = 1;
                    var isRowHeader      = (count == 0 && useRowHeader && dataColumns.Count > 1) ||
                                           (dataColumns.Count == 1 && i == 0 && !hasHeader);

                    if (Regex.Match(dataColumn.Groups[2].Value, @"(\|{2,})").Success)
                    {
                        columnSpanLength = Regex.Match(dataColumn.Groups[2].Value, @"(\|{2,})").Length;
                    }

                    // @UE3 ensure that the index into alignments is not greater than the amount expected. (Users may accidentally add extra || to lines)
                    string alignment = null;
                    if (count >= alignments.Length)
                    {
                        // Report only 1 error per row per run to avoid duplicates
                        if (!tableRow.HasError)
                        {
                            var errorCount = data.ErrorList.Count;
                            tableRow.ErrorId  = errorCount;
                            tableRow.HasError = true;
                            data.ErrorList.Add(
                                Markdown.GenerateError(
                                    Language.Message(
                                        "MoreColumnsThanAllignmentsInOneOfTheTableRowsColumnsIgnored",
                                        Markdown.Unescape(dataRows[i])),
                                    MessageClass.Error,
                                    Markdown.Unescape(dataRows[i]),
                                    errorCount,
                                    data));
                        }
                    }
                    else
                    {
                        alignment = alignments[count];
                    }

                    var cellInformation = (cell.Trim() != "^")
                                              ? new TableCellInformation(
                        parent.Document,
                        new EMElementOrigin(tableDataOffset + map.GetOriginalPosition(addToOffset + rowOffset + dataColumn.Groups[1].Index, PositionRounding.Down), cell),
                        parent, data, columnSpanLength, alignment, isRowHeader)
                                              : new TableCellInformation(columnSpanLength, alignment, isRowHeader, false, 1, true);

                    tableRow.Cells.Add(cellInformation);

                    // Make parsing table easier later, if ColumnSpan > 1 create a blank column for each over one
                    for (var dummyColumnCount = 1; dummyColumnCount < columnSpanLength; ++dummyColumnCount)
                    {
                        tableRow.Cells.Add(new TableCellInformation(0));
                    }

                    // @UE3 this was not in original specification, handles correct alignment of a subsequent column after a long column.
                    count += columnSpanLength;
                }
                // If count is zero check that someone has just not placed a space in the first column indicating it should be empty.

                if (count < alignments.Length)
                {
                    var errorCount = data.ErrorList.Count;
                    tableRow.ErrorId  = errorCount;
                    tableRow.HasError = true;
                    data.ErrorList.Add(
                        Markdown.GenerateError(
                            Language.Message(
                                "LessColumnsThanExpectedInOneOfTheTableRowsEmptyCellsInserted", Markdown.Unescape(dataRows[i])),
                            MessageClass.Error,
                            Markdown.Unescape(dataRows[i]),
                            errorCount,
                            data));
                }

                // If count is less than total expected for a rows data add dummy column and raise error
                for (var dummyColumnCount = count; dummyColumnCount < alignments.Length; ++dummyColumnCount)
                {
                    tableRow.Cells.Add(new TableCellInformation(1, null, false, true));
                }

                tableRows.Add(tableRow);

                rowOffset += dataRow.Length + 1;
            }

            // Now work out rowspans based on Content and character ^
            // Work down rows in columns

            for (var columnNumber = 0; columnNumber < alignments.Length; ++columnNumber)
            {
                var firstNonSpanRow = -1;
                for (var rowNumber = 0; rowNumber < tableRows.Count; ++rowNumber)
                {
                    if (tableRows[rowNumber].Cells[columnNumber].IsRowSpanColumn) //Found a rowspan column
                    {
                        if (rowNumber == 0)
                        {
                            var errorCount = data.ErrorList.Count;
                            tableRows[rowNumber].ErrorId  = errorCount;
                            tableRows[rowNumber].HasError = true;
                            data.ErrorList.Add(
                                Markdown.GenerateError(
                                    Language.Message(
                                        "ColumnCannotBeSetToSpanWithSpecialSymbolInTheFirstRowOfATable", dataRows[0]),
                                    MessageClass.Error,
                                    dataRows[0],
                                    errorCount,
                                    data));
                        }
                        else
                        {
                            if (firstNonSpanRow < 0)
                            {
                                //is this the first detected row for this span?
                                firstNonSpanRow = rowNumber - 1;

                                //Row span above this 1 now should include itself
                                tableRows[firstNonSpanRow].Cells[columnNumber].RowSpanCount = 1;
                            }

                            //Increment the Row above first_row detected by 1
                            tableRows[firstNonSpanRow].Cells[columnNumber].RowSpanCount += 1;
                        }
                    }
                    else if (firstNonSpanRow >= 0)
                    {
                        //This row is not a rowspan but we had one previously so clear for any other rowspans in the column
                        firstNonSpanRow = -1;
                    }
                }
            }

            return(tableRows);
        }
        public void AugmentCompletionSession(SnapshotSpan span, IList<CompletionSet> completionSets)
        {
            var text = span.GetText();

            var map = new PreprocessedTextLocationMap();

            text = VariableManager.CutoutVariableInclusions(text, map);

            var match = LinkStartPattern.Match(text);

            if (!match.Success)
            {
                return;
            }

            var suggestionMatchGroup = match.Groups["suggestion"];
            var pathMatchGroup = match.Groups["path"];

            List<PathElement> list;

            if (match.Groups["link"].Success)
            {
                var isImageLink = match.Groups["image"].Success;

                list =
                    PathCompletionHelper.GetSuggestionList(
                        UDNDocRunningTableMonitor.CurrentUDNDocView.ParsingResultsCache.Results.Document,
                        pathMatchGroup.Value,
                        (!isImageLink ? PathElementType.Attachment : 0) | PathElementType.Folder
                        | ((string.IsNullOrWhiteSpace(pathMatchGroup.Value) && !isImageLink)
                               ? PathElementType.Bookmark
                               : 0) | (isImageLink ? PathElementType.Image : 0));
            }
            else if(match.Groups["include"].Success)
            {
                if (pathMatchGroup.Length == 0)
                {
                    if (match.Groups["hash"].Success)
                    {
                        list = GetLocalSuggestions(PathElementType.Excerpt);
                    }
                    else
                    {
                        list = GetLocalSuggestions(PathElementType.Excerpt)
                                .Select(e => new PathElement("#" + e.Text, e.Type))
                                .ToList();

                        list.AddRange(GetRootFolders());
                    }
                }
                else
                {
                    list =
                        PathCompletionHelper.GetSuggestionList(
                            UDNDocRunningTableMonitor.CurrentUDNDocView.CurrentEMDocument,
                            "%ROOT%/" + pathMatchGroup.Value,
                            match.Groups["hash"].Success ? PathElementType.Excerpt : PathElementType.Folder);
                }
            }
            else if (match.Groups["variable"].Success)
            {
                if (pathMatchGroup.Length == 0)
                {
                    list = GetRootFolders();
                    list.AddRange(GetLocalSuggestions(PathElementType.Variable));
                }
                else
                {
                    var types = match.Groups["colon"].Success ? PathElementType.Variable : PathElementType.Folder;
                    var path = "%ROOT%/" + pathMatchGroup.Value.Substring(0, pathMatchGroup.Length - 1);

                    list = PathCompletionHelper.GetSuggestionList(
                            UDNDocRunningTableMonitor.CurrentUDNDocView.CurrentEMDocument, path, types);
                }
            }
            else
            {
                throw new InvalidOperationException("Should not happen!");
            }

            try
            {
                var trackingSpan = span.Snapshot.CreateTrackingSpan(
                    span.Start + map.GetOriginalPosition(suggestionMatchGroup.Index, PositionRounding.None),
                    suggestionMatchGroup.Length,
                    SpanTrackingMode.EdgeInclusive);

                completionSets.Add(
                    new CompletionSet(
                        "AutoCompletion",
                        "AutoCompletion",
                        trackingSpan,
                        CompletionCreator.SortAndCreateCompletions(list),
                        null));
            }
            catch (UnableToDetectOriginalPositionException)
            {
                // ignore and don't show completions
            }
        }