Browse Source

Fixed merge conflicts

stew
Sarah Inzerillo 3 years ago
parent
commit
621f56c82c
  1. 6
      debug.sh
  2. 69
      docs/design.md
  3. 3
      docs/sample_interface.txt
  4. 60
      docs/specification.md
  5. 59
      docs/specification.txt
  6. 218
      src/Buffer.cpp
  7. 11
      src/Buffer.h
  8. 44
      test.txt

6
debug.sh

@ -1,5 +1,11 @@
#!/bin/bash
if [ ! -d obj ]; then
mkdir obj
fi
cd obj
g++ ../src/*.cpp -c -g
cd ..
if [ ! -d bin ]; then
mkdir bin
fi
g++ obj/*.o -o bin/FileBrowser

69
docs/design.md

@ -0,0 +1,69 @@
# File Browser
## DESIGN DOCUMENT
### COMPONENT: class FileBrowser
A simple file browser. See program specification for details.
#### Public method:
* void run()
Runs the browser.
**Implementation note**: Holds the lines of text in a Buffer object. The displaying of the buffer contents and the execution of the commands is delegated to the Buffer object.
Collaborator: Buffer.
### COMPONENT: class Buffer
A buffer for a simple file browser. Holds the lines of text and executes commands on them. Displays the contents of the buffer. See program specification for details on commands.
#### Public methods:
* Buffer()
(Compiler-generated.) Creates an empty buffer.
* void display() const
Displays the lines of text that the user is currently viewing.
* const string & file_name() const
Returns the name of the file.
* bool go(int link)
Goes to the specified link in the current file. This opens the new link file and adds it to the open history.
* void max_links()
Returns the maximum number of links on the page. This is used by the file browser.
* void move_to_next_page()
Self-explanatory.
* void move_to_previous_page()
Self-explanatory.
* bool open(const string & file_name)
Executes the corresponding file viewer command on the buffer. See program specification for details. The method open returns true if successful.
* void set_maximum_length(int l)
Self-explanatory.
* void set_window_height(int h)
Self-explanatory.
**Implementation note**: Stores each line of text as a string and all the lines in a vector. Also stores the index of the line currently displayed at the top of the window, as well as the name of the file and the window height.

3
docs/sample_interface.txt

@ -13,7 +13,8 @@ preface.txt
11 In fact, the creation of large computer programs poses three basic
12 challenges. The overall goal of these notes is to teach you
--------------------------------------------------
next previous open quit
next previous open
go back quit
-------
command: o
file: introduction.txt

60
docs/specification.md

@ -0,0 +1,60 @@
File browser
# SPECIFICATION
## OVERVIEW
A simple file browser that allows the user view the contents of a text file.
## DETAILS
The program interacts with the user as shown in the following example:
```
preface.txt
--------------------------------------------------
1 These notes are for a second course on computer programming and
2 software development. In a first course, you likely focused on
3 learning the basics: variables, control statements, input and
4 output, files, vectors (or arrays), functions and structures. You
5 may have also had an introduction to classes. These concepts are
6 critically important and they are sufficient for the creation of
7 many useful programs. But many other programs, especially large
8 ones, require more powerful concepts and techniques. And a deeper
9 understanding of classes and design principles.
10
11 In fact, the creation of large computer programs poses three basic
12 challenges. The overall goal of these notes is to teach you
--------------------------------------------------
next previous open quit
-------
command: o
file: introduction.txt
```
The program begins by asking the user for a window height. This is the number of lines that will be displayed as each "page". Then, the user will be asked for the maximum number of characters displayed per line. The displayed lines are numbered starting at 1 for the first line of the file. If the number of lines on the last page is smaller than the window height, the rest of the window is filled with unnumbered empty lines.
Each page is displayed between two lines of 50 dashes. The name of the file is printed above the first line of dashes. If no file is currently open, the string "<no file opened>" is printed instead of the file name.
Below the second line of dashes, a menu of commands is displayed. Below that menu, the prompt "choice:" is displayed. The user types the first letter of a command, the command executes and everything is redisplayed. Some commands prompt the user for more information.
Here is a description of the various commands:
* open: Asks for a file name (with prompt "file:") and displays that file after parsing the proper tags and links. If a file named X does not open, the message "ERROR: Could not open X" is displayed just before the file name is redisplayed.
* next: The next page is displayed. Does nothing if the last line of the file is already displayed.
* previous: The previous page is displayed. Does nothing if the first line of the file is already displayed.
* go: Asks for the number of the link the user would like to visit. If the file corresponding to that link does not open, the message "ERROR: ....." is displayed.
* back: The last file that was displayed gets re-opened. If there are no files left in the history, the error message "ERROR: ...." is displayed.
* quit: Stops the program.
## NOTES FOR LATER VERSIONS
Add more error-checking. For example, check that commands are entered properly and that the window height is a positive integer.

59
docs/specification.txt

@ -1,59 +0,0 @@
File browser
SPECIFICATION
OVERVIEW
A simple file browser that allows the user view the contents of a text file.
DETAILS
The program interacts with the user as shown in the following example:
preface.txt
--------------------------------------------------
1 These notes are for a second course on computer programming and
2 software development. In a first course, you likely focused on
3 learning the basics: variables, control statements, input and
4 output, files, vectors (or arrays), functions and structures. You
5 may have also had an introduction to classes. These concepts are
6 critically important and they are sufficient for the creation of
7 many useful programs. But many other programs, especially large
8 ones, require more powerful concepts and techniques. And a deeper
9 understanding of classes and design principles.
10
11 In fact, the creation of large computer programs poses three basic
12 challenges. The overall goal of these notes is to teach you
--------------------------------------------------
next previous open quit go back
-------
command: o
file: introduction.txt
The program begins by asking the user for a window height. This is the number of lines that will be displayed as each "page". The displayed lines are numbered starting at 1 for the first line of the file. If the number of lines on the last page is smaller than the window height, the rest of the window is filled with unnumbered empty lines.
Each page is displayed between two lines of 50 dashes. The name of the file is printed above the first line of dashes. If no file is currently open, the string "<no file opened>" is printed instead of the file name.
Below the second line of dashes, a menu of commands is displayed. Below that menu, the prompt "choice:" is displayed. The user types the first letter of a command, the command executes and everything is redisplayed. Some commands prompt the user for more information.
Here is a description of the various commands:
next: The next page is displayed. Does nothing if the last line of the file is already displayed.
previous: The previous page is displayed. Does nothing if the first line of the file is already displayed.
open: Asks for a file name (with prompt "file:") and displays that file. If a file named X does not open, the message "ERROR: Could not open X" is displayed just before the file name is redisplayed.
go: Asks for the number of the link the user would like to visit. If the file corresponding to that link does not open, the message "ERROR: ....." is displayed.
back: The last file that was displayed gets re-opened. If there are no files left in the history, the error message "ERROR: ...." is displayed.
quit: Stops the program.
NOTES FOR LATER VERSIONS
Add more error-checking. For example, check that commands are entered properly and that the window height is a positive integer.

218
src/Buffer.cpp

@ -1,4 +1,4 @@
// Buffer.cpp
//Buffer.cpp
#include "Buffer.h"
@ -15,49 +15,55 @@ void Buffer::display() const
}
}
vector<string> Buffer::split_line(string & str) {
//Initialize the substring and set the positions in the string where they need to exist
//Pass the string by copy because I don't want to change the original, but still need to manipulate it
vector<string> Buffer::split_line(string str) {
vector<string> v = {};
string str_part = str;
size_t curr_pos = str_part.find(" ");
size_t total_pos = curr_pos;
bool searching = true;
// Split up the lines
//Split up the lines
while (str.length() > maximum_length_)
{
//Re-initialize the substring and set the positions in the string where they need to exist
str_part = str;
curr_pos = str_part.find(" ");
total_pos = curr_pos;
searching = true;
//Initialize the substring and set the positions in the string where they need to exist
string str_part = str;
size_t os = str_part.find(" ");
size_t total_pos = os;
bool searching = true;
//While searching for the next space in a string
while (searching)
{
str_part = str_part.substr(curr_pos + 1, str_part.length());
curr_pos = str_part.find(" ");
if (curr_pos == -1)
str_part = str_part.substr(os + 1, str_part.length());
os = str_part.find(" ");
if (os == -1)
{
searching = false;
}
else if (total_pos + curr_pos + 1 > maximum_length_)
else if (total_pos + os + 1 > maximum_length_)
{
searching = false;
}
else
{
total_pos += curr_pos + 1;
total_pos += os + 1;
}
}
str_part = str.substr(0, total_pos);
str = str.substr(total_pos + 1, str.length());
v.push_back(str_part);
//Check if the string part can still be chopped
if (str_part.length() != str.length()) {
str_part = str.substr(0, total_pos);
cout << str_part << endl;
str = str.substr(total_pos + 1, str.length());
v.push_back(str_part);
}
//Break out of the loop because there is no way to make the string shorter
//I also didn't see why I can't use break and would have to use a boolean
else {
break;
}
}
v.push_back(str);
//for (auto e: v)
// cout << e << endl;
return v;
}
@ -75,99 +81,93 @@ size_t Buffer::get_tag_(const string & line)
bool Buffer::open(const string & new_file_name)
{
std::ifstream file(new_file_name);
if (!file)
return false;
std::ifstream file(new_file_name);
if (!file)
return false;
v_lines_.clear();
// Note: the vector is cleared only after we know the file
// opened successfully.
v_lines_.clear();
//Note: the vector is cleared only after we know the file
//opened successfully.
int curr_link = 0;
std::string curr_l, line;
while(getline(file, line))
{
int curr_link = 0;
std::string curr_line, line;
while(getline(file, line))
{
//Find tags and process them.
for(auto tag_loc = line.find("<a "); tag_loc != -1; tag_loc = line.find("<a", tag_loc + 1))
{
++curr_link;
// Remove any newlines that are in the file.
for(auto char_loc = line.find_first_of('\n'); char_loc != -1; char_loc = line.find_first_of('\n'))
line.erase(char_loc, 1);
// Replace break tags with newlines.
for(auto char_loc = line.find("<br>"); char_loc != -1; char_loc = line.find("<br>"))
line.replace(char_loc, 4, "\n");
// Find link tags and process them.
// Find tags and process them.
for(auto tag_loc = line.find("<a "); tag_loc != -1; tag_loc = line.find("<a", tag_loc + 1))
{
++curr_link;
// Find the length of the tag and pull out the data from the tag.
auto tag_len = line.find_first_of('>', tag_loc) - tag_loc;
std::string link_tag = line.substr(tag_loc + 3, tag_len - 3);
// Seperate the link path and link name into seperate strings. Assuming no spaces in the link path.
auto second_space_loc = link_tag.find_first_of(' ', 0);
std::string file_name = link_tag.substr(0, second_space_loc);
std::string link_name = link_tag.substr(second_space_loc + 1);
// Adds the link as a pair to a vector of links.
v_links_.push_back({file_name, link_name});
// Reformat the link tag to match specification.
line.replace(tag_loc, tag_len + 1, "<" + link_name + ">[" + to_string(curr_link) + "]");
}
// Search for all paragraphs and breaks in the line and add them to the v_lines vector.
for(auto _tag = get_tag_(line); _tag != -1; _tag = get_tag_(line))
{
// Check to see if we have a paragraph tag, so we can add a blank line.
bool is_p = _tag == line.find("<p>");
int tag_len = is_p ? 3 : 4;
// Seperate out text that should stay in the previous line and text that goes in the new line. Delete the tag in the process.
std::string extra_text = line.substr(_tag + tag_len);
line.erase(_tag);
curr_l += line;
// However, if the paragraph is empty, then it shouldn't be added.
if(curr_l != "")
{
v_lines_.push_back(curr_l);
curr_l = "";
}
// 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.
if(curr_l != "")
{
v_lines_.push_back(curr_l);
curr_l = "";
if(is_p)
{
v_lines_.push_back("");
}
}
// Move any remaining data on the line back into the line variable so that it can be processed.
line = extra_text;
}
// 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.
curr_l += " " + line;
}
//Find the length of the tag and pull out the data from the tag.
auto tag_len = line.find_first_of('>', tag_loc) - tag_loc;
std::string link_tag = line.substr(tag_loc + 3, tag_len - 3);
//Separate the link path and link name into separate strings. Assuming no spaces in the link path.
auto second_space_loc = link_tag.find_first_of(' ', 0);
std::string file_name = link_tag.substr(0, second_space_loc);
std::string link_name = link_tag.substr(second_space_loc + 1);
//Adds the link as a pair to a vector of links.
v_links_.push_back({file_name, link_name});
//Reformat the link tag to match specification.
line.replace(tag_loc, tag_len + 1, "<" + link_name + ">[" + to_string(curr_link) + "]");
}
//Search for all paragraphs and breaks in the line and add them to the v_lines vector.
for(auto _tag = get_tag_(line); _tag != -1; _tag = get_tag_(line))
{
// Push the contents of curr_p as it has the last line in the file.
v_lines_.push_back(curr_l);
//Check to see if we have a paragraph tag, so we can add a blank line.
bool is_p = _tag == line.find("<p>");
int tag_len = is_p ? 3 : 4;
file_name_ = new_file_name;
ix_top_line_ = 0;
//Separate out text that should stay in the previous line and text that goes in the new line. Delete the tag in the process.
std::string extra_text = line.substr(_tag + tag_len);
line.erase(_tag);
if(add_to_hist_ == 1){
curr_line += line;
//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.
if(curr_line != "")
{
//TODO This is causing some issues
v_lines_.push_back(curr_line);
curr_line = "";
if(is_p)
{
v_lines_.push_back("");
}
}
//Move any remaining data on the line back into the line variable so that it can be processed.
line = extra_text;
}
curr_line += line;
//Checks if the current line length is greater than the max,
//then splits it up and adds it to the vector if it is
if (curr_line.length() > maximum_length_) {
vector<string> v_split_line = split_line(curr_line);
for (auto e: v_split_line) {
v_lines_.push_back(e);
}
curr_line = "";
}
}
//Push the contents of as it has the last line in the file.
v_lines_.push_back(curr_line);
ix_top_line_ = 0;
file_name_ = new_file_name;
if(add_to_hist_ == 1){
v_hist_.push_back(file_name_);
curr_link_itr = v_hist_.end() - 1;
}
return true;
}
return true;
}
bool Buffer::go(int link)
@ -188,12 +188,12 @@ bool Buffer::back()
{
if(v_hist_.empty())
return false;
cout << endl;
curr_link_itr = curr_link_itr - 1;
v_hist_.erase(curr_link_itr + 1);
if(v_hist_.empty())
return false;
add_to_hist_ = 0;
open(*curr_link_itr);

11
src/Buffer.h

@ -13,13 +13,13 @@
class Buffer
{
public:
bool back();
void display() const;
const std::string & file_name() const { return file_name_; }
bool go(int link);
long max_links() {return v_links_.size(); };
void move_to_next_page();
void move_to_previous_page();
int max_links();
bool back();
bool open(const std::string & file_name);
void set_maximum_length(int l) { maximum_length_ = l; }
void set_window_height(int h) { window_height_ = h; }
@ -27,7 +27,7 @@ public:
private:
std::size_t get_tag_(const std::string & line);
std::string file_name_;
std::vector<std::string> split_line(std::string & str);
std::vector<std::string> split_line(std::string str);
std::vector<std::string> v_lines_;
std::vector<std::pair<std::string, std::string>> v_links_;
std::vector<std::string> v_hist_;
@ -52,9 +52,4 @@ inline void Buffer::move_to_previous_page()
ix_top_line_ = 0;
}
inline int Buffer::max_links()
{
return v_links_.size();
}
#endif

44
test.txt

@ -1,48 +1,6 @@
<<<<<<< HEAD
<p> This is the first line in the file.
<p> This is the second <br> and third line of the file.
<p> This line has a link to the <a docs/specification.txt specification> file.
<p> This line has a link to the <a docs/specification.md specification> file.
<p> This line is split into <p> two paragraph tags.
<p> This line contains some<br> problematic<p> tags.
<p> This has a link to sarahs <a sarahTest.txt anotherLink> file.
=======
<p>This is the first line in the file.
<p>This is the second <br> and third line of the file.
<p>This line has a link to the <a docs/specification.txt specification> file.
<p>This line is split into <p>two paragraph tags.
<p>This line con<br>tains some<br > problematic< p> tags.
Derp. Derp. Derp. Derp. Derp.
<<<<<<< HEAD
>>>>>>> d20176994a49dc433604ed3b1b96b8324f680782
=======
<p>This is the first line in the file.
<p>This is the second <br> and eighth line of the file.
<p>This line has a link to the <a docs/specification.txt specification> file.
<p>This line is split into <p>two paragraph tags.
<p>This line con<br>tains some<br > problematic< p> tags.
Derp. Derp. Derp. Derp. Derp.
<p>This is the first line in the file.
<p>This is the second <br> and fourteenth line of the file.
<p>This line has a link to the <a docs/specification.txt specification> file.
<p>This line is split into <p>two paragraph tags.
<p>This line con<br>tains some<br > problematic< p> tags.
Derp. Derp. Derp. Derp. Derp.
<p>This is the first line in the file.
<p>This is the second <br> and twentieth line of the file.
<p>This line has a link to the <a docs/specification.txt specification> file.
<p>This line is split into <p>two paragraph tags.
<p>This line con<br>tains some<br > problematic< p> tags.
Derp. Derp. Derp. Derp. Derp.
<p>This is the first line in the file.
<p>This is the second <br> and twenty sixth line of the file.
<p>This line has a link to the <a docs/specification.txt specification> file.
<p>This line is split into <p>two paragraph tags.
<p>This line con<br>tains some<br > problematic< p> tags.
Derp. Derp. Derp. Derp. Derp.
<p>This is the first line in the file.
<p>This is the second <br> and thirty second line of the file.
<p>This line has a link to the <a docs/specification.txt specification> file.
<p>This line is split into <p>two paragraph tags.
<p>This line con<br>tains some<br > problematic< p> tags.
Derp. Derp. Derp. Derp. Derp.
>>>>>>> 9159d27c4f65480ce2606eeb041b3ce03a1b1048
Loading…
Cancel
Save