Exemple #1
0
        /// <summary>
        /// Scale the widths given in the column specification to split up the specified full width as evenly as possible
        /// </summary>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown if the width is smaller than the number of columns</exception>
        public static int[] ScaleColumnWidths(int fullWidth, ColumnFormat[] columnFormats)
        {
            fullWidth = Math.Abs(fullWidth);

            // Two small to fit anything in
            if (fullWidth < columnFormats.Length) { throw new ArgumentOutOfRangeException("fullWidth"); }

            int[] specifiedWidths = columnFormats.Select(c => c.Width).ToArray();
            return ColumnFormat.ScaleWidths(fullWidth, specifiedWidths);
        }
Exemple #2
0
        private static ColumnFormat[] Helper(bool firstColumnMustBeVisible, params int[] widths)
        {
            ColumnFormat[] formats = new ColumnFormat[widths.Length];
            for (int i = 0; i < widths.Length; ++i)
            {
                formats[i] = new ColumnFormat(widths[i]);
            }

            if (firstColumnMustBeVisible) formats[0].Visibility = ContentVisibility.ShowAll;

            return formats;
        }
Exemple #3
0
        /// <summary>
        /// Scale the widths given in the column specification to split up the specified full width as evenly as possible
        /// </summary>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown if the width is smaller than the number of columns</exception>
        public static int[] ScaleColumnWidths(int fullWidth, ColumnFormat[] columnFormats)
        {
            fullWidth = Math.Abs(fullWidth);

            // Two small to fit anything in
            if (fullWidth < columnFormats.Length)
            {
                throw new ArgumentOutOfRangeException("fullWidth");
            }

            int[] specifiedWidths = columnFormats.Select(c => c.Width).ToArray();
            return(ColumnFormat.ScaleWidths(fullWidth, specifiedWidths));
        }
Exemple #4
0
        private static           ColumnFormat[] Helper(bool firstColumnMustBeVisible, params int[] widths)
        {
            ColumnFormat[] formats = new ColumnFormat[widths.Length];
            for (int i = 0; i < widths.Length; ++i)
            {
                formats[i] = new ColumnFormat(widths[i]);
            }

            if (firstColumnMustBeVisible)
            {
                formats[0].Visibility = ContentVisibility.ShowAll;
            }

            return(formats);
        }
Exemple #5
0
        private static int[] ScaleWidths(int fullWidth, int[] widths)
        {
            int[] columnWidths   = new int[widths.Length];
            int   remainingWidth = fullWidth;

            int fractionalWidths = 0;

            // Add up the specified widths
            for (int i = 0; i < columnWidths.Length; i++)
            {
                fractionalWidths += (columnWidths[i] = widths[i]);
            }

            // Scale up to whole numbers, adding any remainder
            bool   zeroSpace       = false;
            double widthMultiplier = (double)fullWidth / fractionalWidths;

            for (int i = 0; i < columnWidths.Length; i++)
            {
                int scaledWidth = (int)(columnWidths[i] * widthMultiplier);
                if (scaledWidth == 0)
                {
                    zeroSpace       = true;
                    columnWidths[i] = 1;
                }
                else
                {
                    columnWidths[i] = scaledWidth;
                }

                remainingWidth -= columnWidths[i];
            }

            if (remainingWidth > 0)
            {
                columnWidths[columnWidths.Length - 1] += remainingWidth;
            }

            if (zeroSpace)
            {
                // Recursing should continue to drop us down to a truer fit
                return(ColumnFormat.ScaleWidths(fullWidth, columnWidths));
            }
            else
            {
                return(columnWidths);
            }
        }
Exemple #6
0
 /// <summary>
 /// Creates a standard table with a header row with the specifed widths (forcing first column visibility)
 /// </summary>
 public static Table Create(params int[] widths)
 {
     return(new Table(ColumnFormat.FromWidths(widths)));
 }
Exemple #7
0
        // Font Colors:
        // ============
        // Red-    \red255\green0\blue0;
        // Orange- \red255\green192\blue0;
        // Yellow- \red255\green255\blue0;
        // Green-  \red0\green176\blue80;
        // Blue-   \red0\green77\blue187;
        // Purple- \red155\green0\blue211;

        // Highlight Colors:
        // =================
        // Yellow-    \red255\green255\blue0;
        // Green-     \red0\green255\blue0;
        // LightBlue- \red0\green255\blue255;
        // Pink-      \red255\green0\blue255;

        // {\colortbl ;}
        // \highlight1/0
        // \cf1/0

        public override void Write(ITable table)
        {
            // <row>    (<tbldef> <cell>+ <tbldef> \row) | (<tbldef> <cell>+ \row) | (<cell>+ <tbldef> \row)
            // <cell>   (<nestrow>? <tbldef>?) & <textpar>+ \cell

            //  12 point font
            //  6 point padding  (120 twips)
            //  14 point height  (280 twips)
            //  6.5" total width (9360 twips)

            // Calculate widths (default 1n), converting to fractions of 6.5" in twips (9360)
            int[] columnWidths = ColumnFormat.ScaleColumnWidths(9360, table.ColumnFormats);

            // Create the row header
            //   \trowd        // Start row
            //   \trgaph120    // Half space between cells in twips (6pt)
            //   \trrh280      // Row height in twips (0 auto, + at least, - exact) (14pt)
            //   \trpaddl120   // Cell left padding (6pt)
            //   \trpaddr120   // Cell right padding
            //   \trpaddfl3    // Left padding unit is twips
            //   \trpaddfr3    // Right padding unit is twips
            StringBuilder rowHeader = new StringBuilder(128);

            rowHeader.AppendFormat(@"{{\trowd\trgaph{0}\trrh-{1}\trpaddl{0}\trpaddr{0}\trpaddfl3\trpaddfr3",
                                   RichTextLogger.FontSize / 2 * RichTextLogger.TwipsPerPoint,    // Padding of half the font size
                                   (RichTextLogger.FontSize + 2) * RichTextLogger.TwipsPerPoint); // Row height, negative to make "exactly"

            int totalWidth = 0;

            for (int i = 0; i < columnWidths.Length; i++)
            {
                totalWidth += columnWidths[i];
                rowHeader.Append(@"\cellx");
                rowHeader.Append(totalWidth);
            }

            bool headerRow = table.HasHeader;

            this.priorControlCharacter = false;
            foreach (var row in table.Rows)
            {
                this.richText.Append(rowHeader);
                if (headerRow)
                {
                    this.richText.Append(@"\b");
                }
                for (int i = 0; i < row.Length; i++)
                {
                    string alignment;
                    switch (table.ColumnFormats[i].Justification)
                    {
                    case Justification.Centered:
                        alignment = @"\qc";
                        break;

                    case Justification.Right:
                        alignment = @"\qr";
                        break;

                    case Justification.Left:
                    default:
                        alignment = @"\ql";
                        break;
                    }
                    this.richText.AppendFormat(@"\pard\intbl\widctlpar{0} {1}\cell", alignment, this.Escape(row[i]));
                }

                if (headerRow)
                {
                    this.richText.Append(@"\b0");
                    headerRow = false;
                }
                this.richText.Append(@"\row}");
            }
            this.priorControlCharacter = true;
        }
Exemple #8
0
 /// <summary>
 /// Construct a simple format array of x columns of equivalent width, forcing the first to be visible if possible
 /// </summary>
 public static            ColumnFormat[] FromCount(int columns)
 {
     return(ColumnFormat.Helper(firstColumnMustBeVisible: true, widths: new int[columns]));
 }
Exemple #9
0
 /// <summary>
 /// Construct a simple format array of relative column widths, forcing the first to be visible if possible
 /// </summary>
 public static            ColumnFormat[] FromWidths(params int[] widths)
 {
     return(ColumnFormat.Helper(firstColumnMustBeVisible: true, widths: widths));
 }
Exemple #10
0
        public override void Write(ITable table)
        {
            // Get the desired column widths in characters
            int columnCount = table.ColumnFormats.Length;

            int[] columnWidths = ColumnFormat.ScaleColumnWidths(this.TableWidth, table.ColumnFormats);

            // Convert tabs to spaces so we can layout properly and
            // get our max widths to see if we fall under the TableWidth
            List <string[]> rowsCopy = new List <string[]>();

            int[] maxColumnWidth = new int[columnCount];
            foreach (var row in table.Rows)
            {
                string[] rowCopy = new string[row.Length];
                for (int i = 0; i < row.Length; i++)
                {
                    rowCopy[i] = Strings.TabsToSpaces(row[i]);
                    if (table.ColumnFormats[i].Visibility.HasFlag(ContentVisibility.CompressWhitespace))
                    {
                        rowCopy[i] = Strings.CompressWhiteSpace(rowCopy[i]);
                    }
                    maxColumnWidth[i] = Math.Max(maxColumnWidth[i],
                                                 rowCopy[i].Length + 1); // We add a space between rows
                }
                rowsCopy.Add(rowCopy);
            }

            // Shrink the columns to fit, expanding the last column if needed with what we trim
            int availableSpace = 0;
            int neededSpace    = 0;

            for (int i = 0; i < columnCount; ++i)
            {
                int overage = columnWidths[i] - maxColumnWidth[i];
                if (overage > 0)
                {
                    availableSpace  += overage;
                    columnWidths[i] -= overage;
                }
                else
                {
                    neededSpace -= overage;
                }
            }

            // Try to fit columns that have required visibility (greedy)
            for (int i = 0; i < columnCount; ++i)
            {
                if (table.ColumnFormats[i].Visibility.HasFlag(ContentVisibility.ShowAll) &&
                    maxColumnWidth[i] > columnWidths[i])
                {
                    int columnNeededSpace = maxColumnWidth[i] - columnWidths[i];
                    if (availableSpace >= columnNeededSpace)
                    {
                        // Plenty available
                        columnWidths[i] += columnNeededSpace;
                        availableSpace  -= columnNeededSpace;
                        neededSpace     -= columnNeededSpace;
                    }
                    else
                    {
                        // Take whatever is available
                        columnWidths[i]   += availableSpace;
                        columnNeededSpace -= availableSpace;
                        neededSpace       -= availableSpace;
                        availableSpace     = 0;

                        // Keep culling a space from available columns while we can
                        while (columnNeededSpace > 0)
                        {
                            for (int j = 0; j < columnCount && columnNeededSpace > 0; j++)
                            {
                                if (!table.ColumnFormats[j].Visibility.HasFlag(ContentVisibility.ShowAll) &&
                                    columnWidths[j] > 4)    // Don't ever go below 4 (3 characters with a buffer space)
                                {
                                    columnWidths[j]--;
                                    columnWidths[i]++;
                                    availableSpace++;
                                    columnNeededSpace--;
                                    neededSpace--;
                                }
                            }

                            // If we were unable to find any more space, bail
                            if (availableSpace == 0)
                            {
                                break;
                            }
                            else
                            {
                                availableSpace = 0;
                            }
                        }
                    }
                }
            }

            // If we still have space and need it, try and fit any "normal" columns by evenly distributing space
            while (neededSpace > 0 && availableSpace > 0)
            {
                for (int i = 0; i < columnCount; ++i)
                {
                    if (maxColumnWidth[i] - columnWidths[i] > 0)
                    {
                        columnWidths[i]++;
                        neededSpace--;
                        if (--availableSpace == 0)
                        {
                            break;
                        }
                    }
                }
            }

            // To make things look nicer, if we have enough space to add a single space to each column, do it
            if (availableSpace >= columnCount)
            {
                for (int i = 0; i < columnCount; ++i)
                {
                    columnWidths[i]++;
                }
            }


            bool headerRow = table.HasHeader;

            StringBuilder rowBuilder = new StringBuilder(TableWidth + 1);

            foreach (var row in rowsCopy)
            {
                rowBuilder.Clear();
                for (int i = 0; i < row.Length; i++)
                {
                    bool lastColumn = (i == row.Length - 1);
                    rowBuilder.WriteColumn(
                        row[i],
                        table.ColumnFormats[i].Justification,
                        columnWidths[i] - 1,
                        lastColumn && !headerRow);

                    if (!lastColumn)
                    {
                        if (headerRow)
                        {
                            rowBuilder.Append('_');
                        }
                        else
                        {
                            rowBuilder.Append(' ');
                        }
                    }
                }

                if (headerRow)
                {
                    WriteLine(WriteStyle.Underline, rowBuilder.ToString());
                    headerRow = false;
                }
                else
                {
                    WriteLine(rowBuilder.ToString());
                }
            }
        }