Example #1
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;
        }
Example #2
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());
                }
            }
        }