You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
4.2 KiB

  1. // Buffer.cpp
  2. #include "Buffer.h"
  3. using namespace std;
  4. void Buffer::display() const
  5. {
  6. int ix_stop_line_ = ix_top_line_ + window_height_;
  7. for (int i = ix_top_line_; i < ix_stop_line_; ++i) {
  8. if (i < v_lines_.size())
  9. cout << std::setw(6) << i+1 << " " << v_lines_[i];
  10. cout << '\n';
  11. }
  12. }
  13. string* Buffer::get_lines() const
  14. {
  15. string* lines = new string[window_height_];
  16. int line = 0;
  17. while (line < window_height_ && line + ix_top_line_ < v_lines_.size()) {
  18. lines[line - ix_top_line_] = v_lines_[line];
  19. ++line;
  20. }
  21. return lines;
  22. }
  23. auto get_tag(const string & line)
  24. {
  25. auto p_tag = line.find("<p>");
  26. auto b_tag = line.find("<br>");
  27. if (p_tag > b_tag)
  28. return b_tag;
  29. else
  30. return p_tag;
  31. }
  32. bool Buffer::open(const string & new_file_name)
  33. {
  34. std::ifstream file(new_file_name);
  35. if (!file)
  36. return false;
  37. v_lines_.clear();
  38. // Note: the vector is cleared only after we know the file
  39. // opened successfully.
  40. int curr_link = 0;
  41. std::string curr_l, line;
  42. while(getline(file, line))
  43. {
  44. // Remove any newlines that are in the file.
  45. for(auto char_loc = line.find_first_of('\n'); char_loc != -1; char_loc = line.find_first_of('\n'))
  46. line.erase(char_loc, 1);
  47. // Replace break tags with newlines.
  48. for(auto char_loc = line.find("<br>"); char_loc != -1; char_loc = line.find("<br>"))
  49. line.replace(char_loc, 4, "\n");
  50. // Find link tags and process them.
  51. // Find tags and process them.
  52. for(auto tag_loc = line.find("<a "); tag_loc != -1; tag_loc = line.find("<a", tag_loc + 1))
  53. {
  54. ++curr_link;
  55. // Find the length of the tag and pull out the data from the tag.
  56. auto tag_len = line.find_first_of('>', tag_loc) - tag_loc;
  57. std::string link_tag = line.substr(tag_loc + 3, tag_len - 3);
  58. // Seperate the link path and link name into seperate strings. Assuming no spaces in the link path.
  59. auto second_space_loc = link_tag.find_first_of(' ', 0);
  60. std::string file_name = link_tag.substr(0, second_space_loc);
  61. std::string link_name = link_tag.substr(second_space_loc + 1);
  62. // Adds the link as a pair to a vector of links.
  63. v_links_.push_back({file_name, link_name});
  64. // Reformat the link tag to match specification.
  65. line.replace(tag_loc, tag_len + 1, "<" + link_name + ">[" + to_string(curr_link) + "]");
  66. }
  67. // Search for all paragraphs and breaks in the line and add them to the v_lines vector.
  68. for(auto _tag = get_tag(line); _tag != -1; _tag = get_tag(line))
  69. {
  70. // Check to see if we have a paragraph tag, so we can add a blank line.
  71. bool is_p = _tag == line.find("<p>");
  72. int tag_len = is_p ? 3 : 4;
  73. // Seperate out text that should stay in the previous line and text that goes in the new line. Delete the tag in the process.
  74. std::string extra_text = line.substr(_tag + tag_len);
  75. line.erase(_tag);
  76. curr_l += line;
  77. // However, if the paragraph is empty, then it shouldn't be added.
  78. if(curr_l != "")
  79. {
  80. v_lines_.push_back(curr_l);
  81. curr_l = "";
  82. }
  83. // However, if the tag is located at the start of the file, there will be no data, so it shouldn't be added as it will be an empty line.
  84. if(curr_l != "")
  85. {
  86. v_lines_.push_back(curr_l);
  87. curr_l = "";
  88. if(is_p)
  89. {
  90. v_lines_.push_back("");
  91. }
  92. }
  93. // Move any remaining data on the line back into the line variable so that it can be processed.
  94. line = extra_text;
  95. }
  96. // Append any data left on this line to the v_line being read. Add a space so that content from two lines can be seperated.
  97. curr_l += " " + line;
  98. }
  99. // Push the contents of curr_p as it has the last line in the file.
  100. v_lines_.push_back(curr_l);
  101. file_name_ = new_file_name;
  102. ix_top_line_ = 0;
  103. v_hist_.push_back(file_name_);
  104. curr_link_itr = v_hist_.end() - 1;
  105. return true;
  106. }
  107. bool Buffer::go(const int & link)
  108. {
  109. string f_name = v_links_[link-1].first;
  110. v_links_.clear();
  111. if(!open(f_name))
  112. return false;
  113. else
  114. {
  115. return true;
  116. }
  117. }
  118. bool Buffer::back()
  119. {
  120. if(v_hist_.empty())
  121. return false;
  122. curr_link_itr = prev(curr_link_itr);
  123. v_hist_.erase(curr_link_itr + 1);
  124. if(v_hist_.size() == 0)
  125. return false;
  126. open(*curr_link_itr);
  127. return true;
  128. }