diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookFormatter.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookFormatter.java new file mode 100644 index 0000000..50f0f9b --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookFormatter.java @@ -0,0 +1,92 @@ +package net.knarcraft.bookswithoutborders.utility; + +import java.util.List; + +/** + * A class for formatting text to fit books + * + *

The book formatter

+ */ +public class BookFormatter { + + /** + * Formats the last page of a set of pages + * + *

If the last page is non-empty and has space, a newline is added. If the last two pages' contents can fit on + * the same page, they will be combined.

+ * + * @param rawPages

A list of pages

+ */ + public static void formatLastPage(List rawPages) { + int maxPageText = 256; + int fitsNewline = maxPageText - 2; + + //Adds newline if the contents of the last page does not exceed page limit and is non-empty + formatLastPageAddNewline(rawPages, fitsNewline); + + //Combines the two last pages if they can fit on one page + if (rawPages.size() > 1) { + formatLastPageCombinePages(rawPages, maxPageText); + } + + //Splits the last page if it is too long + if (rawPages.get(rawPages.size() - 1).length() > maxPageText) { + formatLastPageSplitOverflow(rawPages, maxPageText, fitsNewline); + } + } + + /** + * Splits the last page if it overflows + * @param rawPages

The raw pages to format

+ * @param maxPageText

The max number of characters which fit on a page

+ * @param fitsNewline

The max number of characters on a page which still fits a newline character

+ */ + public static void formatLastPageSplitOverflow(List rawPages, int maxPageText, int fitsNewline) { + while (rawPages.get(rawPages.size() - 1).length() > maxPageText) { + int splitPosition; + String fittingText = rawPages.get(rawPages.size() - 1).substring(0, maxPageText); + int lastSpaceBeforePageBreak = fittingText.lastIndexOf(" "); + + if (lastSpaceBeforePageBreak > -1) { + //Split at space if it exists + rawPages.add(rawPages.get(rawPages.size() - 1).substring(lastSpaceBeforePageBreak + 1)); + splitPosition = lastSpaceBeforePageBreak; + } else { + //Split at text limit + rawPages.add(rawPages.get(rawPages.size() - 1).substring(maxPageText)); + splitPosition = maxPageText; + } + //Adds newline if the contents of the last page does not exceed page limit and is non-empty + formatLastPageAddNewline(rawPages, fitsNewline); + //Removes excess page content + rawPages.set(rawPages.size() - 2, rawPages.get(rawPages.size() - 2).substring(0, splitPosition)); + } + } + + /** + * Combines the two last pages if they can fit on the same page + * @param rawPages

The raw pages to format

+ * @param maxPageText

The max number of characters which fit on a page

+ */ + public static void formatLastPageCombinePages(List rawPages, int maxPageText) { + int lastPageIndex = rawPages.size() - 1; + int nextToLastIndex = rawPages.size() - 2; + if (rawPages.get(nextToLastIndex).length() + rawPages.get(lastPageIndex).length() <= maxPageText) { + rawPages.set(nextToLastIndex, (rawPages.get(nextToLastIndex)) + (rawPages.get(lastPageIndex))); + rawPages.remove(lastPageIndex); + } + } + + /** + * Adds newline if the contents of the last page does not exceed page limit and is non-empty + * @param rawPages

The raw pages to format

+ * @param fitsNewline

The max number of characters on a page which still fits a newline character

+ */ + public static void formatLastPageAddNewline(List rawPages, int fitsNewline) { + int pageIndex = rawPages.size() - 1; + if (rawPages.get(pageIndex).length() <= fitsNewline && !rawPages.get(pageIndex).isEmpty()) { + rawPages.set(pageIndex, (rawPages.get(pageIndex)) + "\n"); + } + } + +}