private void ValidateInputs(ConsoleTableBuilderContext context)
 {
     if (context.OverflowBehaviors.Count != context.ColumnHeaders.Count)
     {
         throw new ArgumentOutOfRangeException("If 'columnOverflowBehaviors' is specified then it must contain the same number of items as 'columns'");
     }
 }
        private void AddCellToTable(ConsoleTableBuilderContext context, int rowIndex, int colIndex)
        {
            var val = context.Rows[rowIndex][colIndex];

            if (context.OverflowBehaviors[colIndex] is TruncateOverflowBehavior)
            {
                val = TruncateIfNeeded((context.OverflowBehaviors[colIndex] as TruncateOverflowBehavior), val);
                while (val.Length < context.ColumnWidths[colIndex] + context.Gutter)
                {
                    val += Space;
                }
            }
            else if (context.OverflowBehaviors[colIndex] is SmartWrapOverflowBehavior)
            {
                var segments = FormatAsWrappedSegments((context.OverflowBehaviors[colIndex] as SmartWrapOverflowBehavior), val);
                val = segments[0];

                if ((context.OverflowBehaviors[colIndex] as SmartWrapOverflowBehavior).DefineMaxWidthBasedOnConsoleWidth == false)
                {
                    while (val.Length < context.ColumnWidths[colIndex] + context.Gutter)
                    {
                        val += Space;
                    }
                }

                for (int segIndex = 1; segIndex < segments.Count; segIndex++)
                {
                    var interrupt = new SmartWrapInterrupt()
                    {
                        Column    = colIndex,
                        Row       = rowIndex + (segIndex - 1),
                        Value     = segments[segIndex],
                        SmartWrap = (context.OverflowBehaviors[colIndex] as SmartWrapOverflowBehavior)
                    };
                    context.SmartWrapInterrupts.Add(interrupt);
                }
            }
            else if (context.OverflowBehaviors[colIndex] is GrowUnboundedOverflowBehavior)
            {
                while (val.Length < context.ColumnWidths[colIndex] + context.Gutter)
                {
                    val += Space;
                }
            }
            else
            {
                throw new NotSupportedException("Unsupported overflow behavior: '" + context.OverflowBehaviors[colIndex].GetType().FullName + "'");
            }

            context.TableOutput.AddRange(val);
        }
Beispiel #3
0
        private void DetermineColumnWidths(ConsoleTableBuilderContext context)
        {
            Dictionary <int, int> ret = new Dictionary <int, int>();

            for (int i = 0; i < context.ColumnHeaders.Count; i++)
            {
                ret.Add(i, context.ColumnHeaders[i].Length);
            }
            for (int i = 0; i < context.ColumnHeaders.Count; i++)
            {
                if (context.OverflowBehaviors[i] is TruncateOverflowBehavior)
                {
                    ret[i] = (context.OverflowBehaviors[i] as TruncateOverflowBehavior).ColumnWidth + (context.OverflowBehaviors[i] as TruncateOverflowBehavior).TruncationText.Length;
                }
                else if (context.OverflowBehaviors[i] is SmartWrapOverflowBehavior)
                {
                    if ((context.OverflowBehaviors[i] as SmartWrapOverflowBehavior).DefineMaxWidthBasedOnConsoleWidth)
                    {
                        if (i != context.ColumnHeaders.Count - 1)
                        {
                            throw new InvalidOperationException("DefineMaxWidthBasedOnConsoleWidth can only be set to true for the last column in a table");
                        }
                        context.LastColumnAutoExpands = true;
                        var left = 0;

                        for (int j = 0; j < i; j++)
                        {
                            left += ret[j] + context.Gutter;
                        }

                        (context.OverflowBehaviors[i] as SmartWrapOverflowBehavior).MaxWidthBeforeWrapping = Console.BufferWidth - left - context.Gutter; // The Gutter is so newlines don't get double rendered on the console
                    }

                    ret[i] = (context.OverflowBehaviors[i] as SmartWrapOverflowBehavior).MaxWidthBeforeWrapping;
                }
                else if (context.OverflowBehaviors[i] is GrowUnboundedOverflowBehavior)
                {
                    foreach (var row in context.Rows)
                    {
                        ret[i] = Math.Max(ret[i], row[i].Length);
                    }
                }
                else
                {
                    throw new NotSupportedException("Unsupported overflow behavior: '" + context.OverflowBehaviors[i].GetType().FullName + "'");
                }
            }

            context.ColumnWidths = ret;
        }
        private void AddCellsToTable(ConsoleTableBuilderContext context)
        {
            for (int rowIndex = 0; rowIndex < context.Rows.Count; rowIndex++)
            {
                context.TableOutput.AddRange(context.RowPrefix);

                for (int colIndex = 0; colIndex < context.ColumnHeaders.Count; colIndex++)
                {
                    AddCellToTable(context, rowIndex, colIndex);
                }

                context.TableOutput.Add(new ConsoleCharacter('\n'));
                ProcessPendingSmartWrapInterrupts(context);
            }
        }
Beispiel #5
0
        private void AddCellsToTable(ConsoleTableBuilderContext context)
        {
            for (int rowIndex = 0; rowIndex < context.Rows.Count; rowIndex++)
            {
                context.TableOutput += context.RowPrefix;

                for (int colIndex = 0; colIndex < context.ColumnHeaders.Count; colIndex++)
                {
                    AddCellToTable(context, rowIndex, colIndex);
                }

                context.TableOutput += "\n";
                ProcessPendingSmartWrapInterrupts(context);
            }
        }
        private void AddColumnHeadersToTable(ConsoleTableBuilderContext context)
        {
            context.TableOutput.AddRange(context.RowPrefix);

            for (int colIndex = 0; colIndex < context.ColumnHeaders.Count; colIndex++)
            {
                var val = context.ColumnHeaders[colIndex];

                if (context.OverflowBehaviors[colIndex] is TruncateOverflowBehavior)
                {
                    val = TruncateIfNeeded((context.OverflowBehaviors[colIndex] as TruncateOverflowBehavior), val);
                    while (val.Length < context.ColumnWidths[colIndex] + context.Gutter)
                    {
                        val += Space;
                    }
                }
                else if (context.OverflowBehaviors[colIndex] is SmartWrapOverflowBehavior)
                {
                    // column headers don't wrap

                    if ((context.OverflowBehaviors[colIndex] as SmartWrapOverflowBehavior).DefineMaxWidthBasedOnConsoleWidth == false)
                    {
                        while (val.Length < context.ColumnWidths[colIndex] + context.Gutter)
                        {
                            val += Space;
                        }
                    }
                }
                else if (context.OverflowBehaviors[colIndex] is GrowUnboundedOverflowBehavior)
                {
                    while (val.Length < context.ColumnWidths[colIndex] + context.Gutter)
                    {
                        val += Space;
                    }
                }
                else
                {
                    throw new NotSupportedException("Unsupported overflow behavior: '" + context.OverflowBehaviors[colIndex].GetType().FullName + "'");
                }

                context.TableOutput.AddRange(val);
            }

            context.TableOutput.Add(new ConsoleCharacter('\n'));
        }
        /// <summary>
        /// Formats the given data as a string that looks and feels like a table when displayed in a console
        /// </summary>
        /// <param name="columnHeaders">The headers for the table</param>
        /// <param name="rows">The cell data for the table</param>
        /// <param name="rowPrefix">A prefix, usually an indentation, to append before each row, including the headers</param>
        /// <param name="columnOverflowBehaviors">Optionally provide hints as to how overflow should be handled.  By default, the longest value in a column determines the column width.  You can choose to truncate or to do a smart wrap.</param>
        /// <param name="gutter">How many empty spaces to place between columns</param>
        /// <returns>The table, as a console string</returns>
        public ConsoleString FormatAsTable(List <ConsoleString> columnHeaders, List <List <ConsoleString> > rows, string rowPrefix = "", List <ColumnOverflowBehavior> columnOverflowBehaviors = null, int gutter = 3)
        {
            ConsoleTableBuilderContext context = new ConsoleTableBuilderContext();

            context.Gutter              = gutter;
            context.ColumnHeaders       = columnHeaders;
            context.Rows                = rows ?? new List <List <ConsoleString> >();
            context.OverflowBehaviors   = columnOverflowBehaviors ?? CreateDefaultOverflowBehavior(context.ColumnHeaders.Count);
            context.TableOutput         = new List <ConsoleCharacter>();
            context.SmartWrapInterrupts = new List <SmartWrapInterrupt>();
            context.RowPrefix           = new ConsoleString(rowPrefix);

            ValidateInputs(context);
            DetermineColumnWidths(context);
            AddColumnHeadersToTable(context);
            AddCellsToTable(context);

            return(new ConsoleString(context.TableOutput));
        }
        private void ProcessPendingSmartWrapInterrupts(ConsoleTableBuilderContext context)
        {
            while (context.SmartWrapInterrupts.Count > 0)
            {
                context.SmartWrapInterrupts.Sort();

                context.TableOutput.AddRange(context.RowPrefix);
                for (int colIndex = 0; colIndex < context.ColumnHeaders.Count; colIndex++)
                {
                    var nextInterruptCol = context.SmartWrapInterrupts.Count > 0 ? context.SmartWrapInterrupts[0].Column : -1;

                    var val = ConsoleString.Empty;
                    if (nextInterruptCol != colIndex)
                    {
                        if (colIndex != context.ColumnHeaders.Count - 1 || !context.LastColumnAutoExpands)
                        {
                            while (val.Length < context.ColumnWidths[colIndex] + context.Gutter)
                            {
                                val += Space;
                            }
                        }
                    }
                    else
                    {
                        val = context.SmartWrapInterrupts[0].Value;
                        if ((context.OverflowBehaviors[colIndex] as SmartWrapOverflowBehavior).DefineMaxWidthBasedOnConsoleWidth == false)
                        {
                            while (val.Length < context.ColumnWidths[colIndex] + context.Gutter)
                            {
                                val += Space;
                            }
                        }

                        context.SmartWrapInterrupts.RemoveAt(0);
                    }
                    context.TableOutput.AddRange(val);
                }

                context.TableOutput.Add(new ConsoleCharacter('\n'));
            }
        }