Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
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);
        }