Efficiently Splitting Text into Pages in Swift

Efficiently Splitting Text into Pages in Swift

Text pagination involves dividing a block of text into smaller chunks, or “pages,” for display or printing. This is a common task in software development, particularly in applications that display or print text. For example, a word processor may need to divide a document into pages for printing, while a text editor may need to divide a large block of text into smaller chunks for display on a screen. The following algorithm, written in Swift, is a simple and effective way to paginate a block of text. It splits the input text into an array of strings, where each string (or “page”) has a maximum number of characters.

One of the benefits of this algorithm is its flexibility. It can be easily modified to fit the specific needs of an application, such as adjusting the maximum number of characters per page or handling text that contains multiple languages or writing systems. If you want to see this algorithm in action, check out Quill, a book reading app for iOS available on the App Store. Quill uses this algorithm to paginate text for display on the screen, making it easier to read and navigate long blocks of text on a mobile device.

            let lines = self.text.components(separatedBy: "\n")
            pages = [String]()
            var page = ""
            for line in lines {
              let wordsInLine = line.components(separatedBy: " ")
              for word in wordsInLine {
                if page.count + word.count + 1 > maxCharactersPerPage {
                  pages.append(page)
                  page = word + " "
                } else {
                  page += word + " "
                }
              }
              if !page.isEmpty {
                page += "\n"
              }
            }

            pages.append(page)

The algorithm begins by using the components(separatedBy:) method to split the input text (self.text) into an array of lines (lines). This method is a function of the String type in Swift that splits a string into an array of substrings based on a given separator string. In this case, the separator is the newline character "\n", so the method will split the input text at each newline and return an array of strings, one for each line of text.

After splitting the input text into lines, the algorithm initializes an empty array of strings (pages) to hold the pages that will be created. This array will be populated with the paginated text as the algorithm processes the input lines.

The algorithm also initializes a string (page) to hold the current page being built. As the algorithm processes each line and word of the input text, it will add them to the page string until it reaches the maximum number of characters per page. At that point, the current page will be added to the pages array and a new page string will be created to hold the next set of lines and words. This initialization sets up the variables that will be used in the pagination process, allowing the algorithm to efficiently split the input text into an array of pages with a maximum number of characters.

Next, the algorithm iterates through each line in the lines array using a forloop. For each line, it splits the line into an array of words (wordsInLine) using the components(separatedBy:) method again, this time using a space character as the separator.

The algorithm then iterates through each word in the wordsInLine array using a nested for loop. For each word, it checks whether adding the word to the current page (page) would exceed the maximum number of characters per page (maxCharactersPerPage). If it would, the current page is added to the pages array and a new page is started with the current word. If it would not, the word is simply added to the current page.

After the inner for loop finishes processing all the words in a line, the algorithm checks whether the current page is empty. If it is not, it adds a newline character to the page using string concatenation. This ensures that each line within a page is preserved, as the newline characters are not stripped when the text is split into pages.

Finally, after the outer for loop finishes processing all the lines, the algorithm adds the current page to the pages array using the append(_:)method. This completes the pagination process and returns an array of pages, each with a maximum number of characters and each line within a page preserved.

Overall, this algorithm is a simple but effective way to paginate a block of text in Swift. It efficiently splits the input text into an array of pages, each with a maximum number of characters and each line within a page preserved.

Thank you for reading! If you have any questions feel free to leave them it the comments.

Did you find this article valuable?

Support Jake Watembach by becoming a sponsor. Any amount is appreciated!