pager.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * BIBISH Is [a] Bible Interactive SHell, a front-end for the SWORD Project
  3. * inspired by Debian's bible package
  4. * Copyright (C) 2015 David "Judah's Shadow" Blue <yudahsshadow@gmx.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation version 2.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. *
  19. */
  20. #include "pager.h"
  21. #include "../back/parser.h"
  22. #include "../back/types.h"
  23. #include <string>
  24. #include <list>
  25. Pager::Pager() {
  26. this->cols = 0;
  27. this->lines = 0;
  28. }
  29. Pager::~Pager() {
  30. }
  31. //This bad boy takes a raw string, and breaks it down into a list of
  32. //of lists (pages) of strings (lines).
  33. std::list<page> Pager::getPagedText(std::string text) {
  34. uint width = this->cols;
  35. uint pageSize = this->lines;
  36. int lineCount = 0;
  37. int colCount = 0;
  38. Parser stringTokenizer;
  39. std::list<std::string> words;
  40. std::string currentWord;
  41. line currentLine;
  42. page currentPage;
  43. std::list<page> pagedText;
  44. words = stringTokenizer.tokenize(text);
  45. while(!words.empty()) {
  46. currentWord = words.front();
  47. words.pop_front();
  48. //Newlines appear within words and not always at EOL, so find them and
  49. //act accordingly.
  50. if(currentWord.find("\n") != std::string::npos) {
  51. int endlPos = 0;
  52. endlPos = currentWord.find("\n");
  53. if(endlPos != currentWord.back()) {
  54. //we've not got an EOL newline, so we need to split it again :/
  55. std::string preEndl = currentWord.substr(0, endlPos);
  56. currentLine += preEndl + "\n";
  57. currentPage.content += currentLine;
  58. currentLine = "";
  59. colCount = 0;
  60. lineCount++;
  61. std::string postEndl = currentWord.substr(endlPos + 1);
  62. currentWord = postEndl;
  63. }
  64. }
  65. if(colCount + currentWord.length() + 1 <= width) {
  66. int newLineCount = 0;
  67. int newLineLoc = 0;
  68. //check for EOL or double EOL at the end of words
  69. if(currentWord.find("\n") != std::string::npos) {
  70. newLineCount++;
  71. newLineLoc = currentWord.find("\n");
  72. currentWord.replace(newLineLoc,1,"");
  73. if(currentWord.find("\n") != std::string::npos) {
  74. newLineCount++;
  75. newLineLoc = currentWord.find("\n");
  76. currentWord.replace(newLineLoc,1,"");
  77. }
  78. }
  79. currentLine += currentWord + " ";
  80. colCount += currentWord.length() + 1;
  81. currentWord = "";
  82. if(newLineCount > 0) {
  83. currentLine += "\n";
  84. currentPage.content += currentLine;
  85. currentLine = "";
  86. if(newLineCount > 1) {
  87. currentLine += "\n";
  88. currentPage.content +=currentLine;
  89. currentLine = "";
  90. }
  91. lineCount += newLineCount;
  92. }
  93. } else {
  94. //TODO: Do stuff about words that are by themselves longer than
  95. //TODO: the width.
  96. currentLine += "\n";
  97. currentPage.content += currentLine;
  98. currentLine = "";
  99. currentLine += currentWord + " ";
  100. colCount = currentWord.length() + 1;
  101. lineCount++;
  102. }
  103. if(lineCount >= pageSize - 3) {
  104. currentPage.lineCount = lineCount;
  105. pagedText.push_back(currentPage);
  106. currentPage.content = "";
  107. lineCount = 0;
  108. currentPage.lineCount = lineCount;
  109. }
  110. }
  111. //Check to see if we have any lines that didn't get pushed and flush them in
  112. if(currentLine.length() > 0) {
  113. currentPage.content += currentLine + "\n";
  114. currentLine = "";
  115. lineCount++;
  116. }
  117. if(currentPage.content.length() > 0) {
  118. currentPage.lineCount = lineCount;
  119. pagedText.push_back(currentPage);
  120. currentPage.content = "";
  121. lineCount = 0;
  122. currentPage.lineCount = lineCount;
  123. }
  124. return pagedText;
  125. }
  126. void Pager::setSize(uint rowSize, uint colSize) {
  127. this->lines = rowSize;
  128. this->cols = colSize;
  129. }