private List <Page> BuildPages(BasePageFormat pageFormat) { var numberOfPages = (int)Math.Ceiling((double)pageFormat.ContentLines.Count / pageFormat.LinesPerPage); var contentLineQueue = new Queue <string>(pageFormat.ContentLines); var pageNumber = 0; var returnList = new List <Page>(); while (contentLineQueue.Any()) { pageNumber++; var longestLineLength = 0; var pageLineIterator = 0; var contentSb = new StringBuilder(); contentSb.AppendLine("```diff"); contentSb.AppendLine($"{pageFormat.HeaderLine}{(!string.IsNullOrEmpty(pageFormat.HorizontalRule) ? Environment.NewLine + pageFormat.HorizontalRule : string.Empty)}"); while (pageLineIterator < pageFormat.LinesPerPage) { if (!contentLineQueue.Any()) { break; } var line = contentLineQueue.Dequeue(); if (line.Length > longestLineLength) { longestLineLength = line.Length; } contentSb.AppendLine(line); pageLineIterator++; } var pageNumSb = new StringBuilder(); pageNumSb.Append($"Page {pageNumber}/{numberOfPages}"); while (pageNumSb.Length < longestLineLength) { pageNumSb.Insert(0, ' '); } contentSb.AppendLine(); contentSb.AppendLine(pageNumSb.ToString()); contentSb.Append("```"); var page = new Page { Content = contentSb.ToString(), PageNumber = pageNumber }; returnList.Add(page); } return(returnList); }
private BasePageFormat Build(bool buildHiddenColumns) { var columnData = _columnData.Where(cd => buildHiddenColumns | !cd.IsHidden).ToList(); var hiddenColumnIndices = _columnData .Where(cd => !buildHiddenColumns & cd.IsHidden) .Select(cd => _columnData.IndexOf(cd)) .ToArray(); var numberOfColumns = columnData.Count; var minimumPageWidth = 80; var maximumPageWidth = 160; List <int> minimumColumnSizes = new List <int>(); for (int i = 0; i < numberOfColumns; i++) { if (hiddenColumnIndices.Contains(i)) { continue; } var minimumColumnSize = Math.Max(_columnData[0].Title.Length, _rowData.Select(rd => rd.Fields[i]?.Length ?? 0).Max()) + 2; minimumColumnSizes.Add(minimumColumnSize); } var projectedWidth = minimumColumnSizes.Sum() + 2 * numberOfColumns + 1; if (projectedWidth > maximumPageWidth) { throw new InvalidOperationException($"Unable to build page format, page width would exceed maximum allowable of {maximumPageWidth} characters"); } List <int> columnSizeActuals = new List <int>(); if (projectedWidth < minimumPageWidth) { var normalizedColumnWidth = minimumPageWidth / numberOfColumns; var extra = minimumPageWidth - projectedWidth; var numberToAddTo = minimumColumnSizes.Count(val => val < normalizedColumnWidth); foreach (var value in minimumColumnSizes.Where(val => val >= normalizedColumnWidth)) { var surplus = value - normalizedColumnWidth; extra -= surplus; } var toAdd = extra / numberToAddTo; foreach (var value in minimumColumnSizes) { if (value >= normalizedColumnWidth) { columnSizeActuals.Add(value); continue; } var newValue = value + toAdd; columnSizeActuals.Add(newValue); } } else { columnSizeActuals = minimumColumnSizes; } var returnValue = new BasePageFormat() { LinesPerPage = _linesPerPage }; var actualWidth = columnSizeActuals.Sum() + numberOfColumns + 1; var headerSb = new StringBuilder(" "); var horizontalRuleSb = new StringBuilder(); var widthShouldBe = 2; for (var i = 0; i < _columnData.Count; i++) { if (hiddenColumnIndices.Contains(i)) { continue; } widthShouldBe += columnSizeActuals[i]; if (i != _columnData.Count - 1) { widthShouldBe += 1; } var column = _columnData[i]; headerSb.Append(column.Title); while (headerSb.Length < widthShouldBe) { headerSb.Append(' '); } } while (horizontalRuleSb.Length < actualWidth) { horizontalRuleSb.Append('-'); } returnValue.HeaderLine = headerSb.ToString(); returnValue.HorizontalRule = horizontalRuleSb.ToString(); var contentLines = new List <string>(); var alternate = false; foreach (var row in _rowData) { contentLines.Add(CreateLine(row, columnSizeActuals, alternate, hiddenColumnIndices)); if (_alternate) { alternate = !alternate; } } returnValue.ContentLines = contentLines; return(returnValue); }