CS 2043 Assignment 1: Maze

Due Date: Wednesday January 30 at 11:15 am

Assignment Captain: Callie Aboaf

Welcome to the maze! Your task is to find a file named “victory” somewhere in a subdirectory of maze. On the way, you’ll see a bunch of files called “README” with hints as to where to look; you should print these out!

Start by logging into wash. Next, we’ll need to make our way into the maze subdirectory. To do this, use the command ls to list the contents of your current directory (your home or ~ directory). Use cd course to move to the course directory. Enter cs2043, assignments, and then maze similarly.

Once inside maze, use the ls command. There is a README located here that contains a hint as to where to look for victory. You can print the README out using cat README. From here on, use the cd, ls, and cat commands to find a file named “victory.”

Once you find “victory,” hand this file in using handin maze victory.

As a refresher, here are some helpful commands:

CS 2043 Assignment 2: Harry Potter and the Chamber of d———

Parts 1 and 2 Due Date: Monday February 4 at 11:15 am

Parts 3 and 4 Due Date: Friday February 8 at 11:15 am

Assignment Captain: Srishti Belwariar

NOTE: If you need to generate a new copy of the assignment, please run the trolls_in_the_dungeon.sh command in project2/ . This will refresh the dungeon directory but not overwrite dungeon-key.sh or blueprint.sh. If you need a new copy of dungeon-key.sh, please move your current dungeon-key.sh out of project2/ and run the trolls_in_the_dungeon.sh command in project2/. Only then will this generate both a new dungeon/ and a new dungeon-key.sh.

Please note: Part 4 requires material we have not yet covered in class. We will be covering the material required to complete this part of the assignment during the next lecture (Monday February 4).

Part 1: Unlocking the Chamber of d———!

Welcome to the Chamber of d———! You and Harry are about to enter the chamber but alas no Parseltounge password can open the chamber this time- only your amazing UNIX tools can help you unlock it!

First let’s get to the entrance of the dungeon. Start by logging into wash. Next, make your way into the dungeon subdirectory. To do this, use the command ls to list the contents of your current directory (your home or ~ directory). Use cd course to move to the course directory. Enter cs2043 and then assignments and then project2 . Use ls to list the contents of the project2 directory. See the dungeon directory? Great! Try entering that directory.

Interestingly enough, you can’t seem to enter the dungeon. Harry’s giving up already but you know exactly how you can get permission to access the dungeon directory.

Task 1: Modify permissions of the dungeon directory so you can

enter. Enter (using cd) into the dungeon directory. Once you’re in, you want to check what’s inside the the dungeon. So take the time to explore this directory using ls and cd . You list out the sub-directories but you can’t enter them or see what’s inside. You don’t even know how many sub-directories and files there are within them. Harry’s ready to give up (again) but you know you can solve this. You remember outside the dungeon (in the project2 directory) there was a dungeon-key.sh file. You should cd back to the project2 directory.
Try opening up dungeon-key.sh and read through the file. Looks like you’ll have to write a few commands to unlock the dungeon fully:

Task 2: Modify dungeon-key.sh, following the directions on the

script. You will be writing commands that will allow you to complete the following 3 tasks:

To run your dungeon-key.sh script, make sure you’re inside the project2 directory and dungeon-key.sh is in this directory.
Run the following command: ./dungeon-key.sh
To check if your script worked, try going back into dungeon and see if you can access its subdirectories and files. Also make sure that you’ve checked that the group and permissions have been changed (Hint: maybe ls can help you with this).
When you’ve completed all the TODOs in dungeon-key.sh, make sure you are in the project2/ directory and hand in your script using handin enter-the-dungeon dungeon-key.sh

Part 2: Making Your Own Secret Room

Now that you’re done with developing your own dungeon key, you’re ready to make your own secret room (directory). Make sure you’re in the project2 folder for this part. Find a partner and create a new script file called blueprint.sh in the project2 directory. You will insert commands in this file that will create a directory in your ~ directory that can’t be accessed by anyone unless they know the secret word (its name) (Hint: think about how you can set permissions so only those who know the name can access it). Don’t tell your partner what the secret word is. Once you’re done, ask your partner to find the secret directory you created through this script. As long as they don’t know the name of the directory, they shouldn’t be able to find it within ~ .
Remember, this secret directory should be in ~ , but ~ has permissions that are restricted right now. Think about how you can allow for your partner to gain access into this directory but still not see the secret room you’ve created.
To run your blueprint.sh script, make sure you’re inside the project2 directory and blueprint.sh is in the project2/ directory. Run the following command: ./blueprint.sh
When you’ve saved your work and are ready to submit, hand in your work using handin secret-room blueprint.sh
Please be aware that you should set the “other” and “group” permissions of your home directory (and secret directory) to be as restrictive as possible. Give only the permissions needed to access the room, and nothing more. Your partner should be able to do anything they want in the secret room.
In particular, think about which of the read/write/execute permissions you need on your home directory in order to get to the secret room. Make sure to try different things out! Change permissions and make observations about what your partner can and cannot do.

Part 3: Exploring the Dungeon

Harry is impressed by your skills in unlocking the dungeon, but he thinks its time to actually explore the place. Modify dungeon-counts.sh, following the directions on the script. You will be writing commands that will allow you to complete the following 3 tasks:

  • Write a command that determines the total number of subdirectories within dungeon.
  • Write a command that determines the total number of files within dungeon.
  • Write a command that determines the total number of words within all the files of the dungeon directory.

  • To run your dungeon-counts.sh script, make sure you’re inside the followup/ directory and dungeon-counts.sh is in the followup/ directory.
    Run the following command: ./dungeon-counts.sh
    You will be submitting this script once you are done with the remaining part.

    Part 4: Piece Together the Story

    Please note: Part 4 requires material we have not yet covered in class. We will be covering the material required to complete this part of the assignment during the next lecture (Monday February 4).

    You’ll notice that many of the dungeon/ files contain snippets of text.
    We want to combine all the text snippets from all the dungeon/ files so we can form the original text. Your script should properly combine all file contents properly and print this into standard output. To execute the script, make sure you’re in followup/ and execute ./dungeon-story.sh
    Hint: Take a look at the file names and see if you can identify a pattern to help you with completing this task.
    Testing Procedure: You may need to do some testing to ensure the final output is indeed the original text we are looking for. In order to test, make sure you are in the followup/ directory. Execute: ./dungeon-story.sh > test.txt
    This will put the output of your script into a “test.txt” file in the followup/ directory. Now execute: md5sum test.txt
    If you’ve written your script correctly, this should report ‘1aa37d0a873f34121d9c7d3fe2ed5530’ as the sum. If it is off by even one character, the script is incorrect. Some types of errors an output can have include:

  • The ordering of the text snippets is incorrect
  • Not all text snippets are included in the output
  • The test.txt file does not end with a newline. It must have a newline at the end in order to compute the right md5sum value. To check if test.txt ends on a newline, execute cat test.txt. If the terminal prompt $ shows up on the same line as the printed text, then test.txt is missing a newline at the end. If it had a newline ending, then the $ prompt will start on a new line in the terminal.

  • Make sure you’ve checked all your work for parts 3 and 4 before submitting. When you’re ready to submit the two scripts, go back to the project2/ directory and hand in your work using handin explore-the-dungeon followup. You’re finally done with Assignment 2!

    CS 2043 Assignment 3: vonne-git

    Due Date: Wednesday February 13 11:15 am

    Assignment Captain: Irene Yoon

    In this assignment, we will be learning the fundamentals of Git through a Kurt Vonnegut-themed story. If you would like a de-themed version of the assignment, please go here.

    The Task sections complete parts of the assignment that must be completed for submission. The Git Parable sections will help you gain intuition about how git works. No part of the Git Parable sections require submission.

    Let’s git going!

    If you would like to reset (get a fresh copy) of any part of the assignment, please run ./reset.sh <part_name>. For instance, if you would like to reset part1, run ./reset.sh part1, and you’ll get a fresh copy of part1 under part1_fresh/. You MUST delete your old copy of partX/ and rename partX_fresh to partX for submission.

    Part 1: It’s Tralfamadorian Time! ⏰

    Tralfamadorians are back – your favorite green-eyed, time-bending, toilet plunger-like aliens! This time, they’ve chosen to abduct YOU for a lesson on time and the fourth dimension (git).

    Here: qkfzca , your Tralfamadorian abductress, will guide you through your enlightenment.

    Time is just Snapshots 📸

    qkfzca : “All moments, past, present and future, always have existed, always will exist. Us Tralfamadorians can look at all the different moments just that way we can look at a stretch of the Rocky Mountains, for instance. We can see how permanent all the moments are, and we can look at any moment that interests them. It is just an illusion that for Earthlings one moment follows another one, like beads on a string, and that once a moment is gone it is gone forever.”

    Luckily, we are able to experience time just like the Tralfamadorians with our fourth-dimensional tool, git!

    Task: So it goes.

    Find part1/ under tralfamadorian-git-gud/. (Don’t worry about part1_dethemed/. This is the dethemed version of part1, and you will get equal credit for submitting either version.)

    You’ll find the following file structure:

    .git/
    billy.txt
    

    If you happen to open up billy.txt, you will see that Billy is dead. You wish Billy were still alive. qkfzca is back again to spread more Tralfamadorian wisdom…

    qkfzca : “That’s one thing Earthlings might learn to do, if they tried hard enough: Ignore the awful times and concentrate on the good ones.”

    Here’s your task: REVIVE BILLY (Tralfamadorians may disagree whether this is actual revival or not) using your time-travelling git powers! Billy’s entire life has been kept track by git, and you can revive Billy through exploring snapshots of his life.

    You can go back to any snapshot where Billy was alive.

    Hint: a couple of useful git commands that may help you. Feel free to use man generously.

    git log
    git checkout
    git reset
    

    WARNING: you will receive no credit for using three-dimensional (plain file editing) powers. You must use git to “revive” Billy!

    Note:

    For this part of the assignment, you do not need to make any extra snapshots.

    If you run git status under part1/, you need to see this output on your terminal once you’ve completed this part.

    On branch master
    nothing to commit, working tree clean
    

    Once you can see this and find that the most recent commit is where “Billy is alive”, you have successfully completed the assignment.

    Git Parable: Snapshots

    Version control systems (VCS) such as git take snapshots of your time. Think of them as save points in a video game. You can take snapshots of your codebase at anytime and resurrect that code on demand.

    To make it easy to remember what changes you made in each snapshot (usually called a commit), git requires you to tag your snapshot with a commit message.

    Once you’re done with Part 1, hand it in by running handin vonne-git-1 part1/.

    Part 2: A Tralfamadorian Stage 🎤

    This is (probably) Billy’s message of gratitude after his “revival”:

    Billy : “It is (has been) time for me to be dead for a little while - and then live again. (Thanks.)”

    Billy is alive, but this doesn’t change the fact that you’re still abducted by our lovely qkfzca .

    qkfzca : “Well, here we are, trapped in the amber of this moment. There is no why.”

    Git Parable: Staging

    Snapshots can be represented as commits. When you’re working on a project, you want to have explicit control over what is captured in each snapshot.

    A staging directory is a set of changes (i.e. modified files) that you wish to capture in the next snapshot. In order to add files to your current staging directory, you can use git add (refer to its man page for more details).

    Task: Staging

    This exercise will have you stage and commit in a particular order, so you can have a better sense of control over your git workflow.

    Go to part2/ to explore our upcoming Tralfamadorian Stage.

    Surprise, qkfzca has planned a stage for you! However, you find that you need to relay pieces of information in a certain order.

    In part2/, you should see the following files:

    .git/
    juggle.txt
    jumprope.txt
    jazz-hands.txt
    

    As Tralfamadorians can only see time through snapshots (commits), you MUST provide your performance in snapshots. It is crucial that the snapshots are given in an order that will amuse them.

    According to another Earthling waiting to perform, the trick is:

    ?? : “Jazz hands, Jumprope, THEN Juggle. Nothing else is acceptable around here.”

    To survive this stage, provide snapshots that contain each of juggle, jumprope, and jazz hands in the order that is Tralfamadorian-approved. Do not provide a single snapshot with all three performances staged at once.

    Hint: try running git status and git diff

    Hint 2: you can use git commit -m "<message>" to commit a snapshot with a message.

    qkfzca : “Each clump of symbols is a brief, urgent message– describing a situation, a scene. We Tralfamadorians read them all at once.”

    When you’re done, you’ll have a commit chain, comprising of commit nodes that point to previous commits. Your commit chain should look “linear”, and each commit should be adding a single file to the snapshot:

       juggle
    
         |
         v
    
      jumprope
    
         |
         v
    
      jazz hands
    

    Time goes up; juggle is the latest.

    Do not provide a single snapshot with all three performances staged at once.

    (For instance, running

    git add .
    git commit -m "I've committed everything"
    

    will be incorrect, as it provides exactly a single snapshot with all three performances staged at the same time.)

    For credit, each commit message must contain information about what is being committed (i.e. if you’re juggling, your commit message should contain the word “juggle”; jumproping - “jump”; jazz handing - “jazz”).

    Once you’re done with Part 2, hand it in by running handin vonne-git-2 part2/.

    Git Parable: Branching

    Recall our “linear” commit chain.Time goes up; juggle is the latest.

       juggle
    
         |
         v
    
      jumprope
    
         |
         v
    
     jazz hands
    

    Imagine this is going to be your stable release for a Tralfamadorian software (that jazz hands, jumpropes, then juggles.). You release the software at the point of juggle.

    A month passes by and you decide to add more snapshots. Time goes up; unicycling is the latest.

       unicycling
    
         |
         V
    
       juggle (release)
    
         |
         V
    
      jumprope
    
         |
         V
      jazz hands
    
    

    Unfortunately, bug reports start filing in and people start having problems with your juggling. You decide to fix the bug in a snapshot called fixed-juggle and re-release your code. However, you don’t want to release your unicycling snapshot.

    Here, we find a couple problems that cannot be solved by our linear workflow. First, we don’t know where our fixed-juggle snapshot will go. Second, we need a way for both unicycling and fixed-juggle have a reference to the original juggle snapshot, so that the snapshot history is not lost.

    As a solution, git introduces a tree structure to its workflow, where we can have branches to keep track of any non-linear workflow. Time goes up; both unicycling and fixed-juggle are the latest.

      unicycling    fixed-juggle (release)
         |           /
         V        /
       juggle
    
         |
         V
    
      jumprope
    
         |
         V
    
     jazz hands
    
    

    Part 3: Tralfamadorian Trivia Night 🌙

    As our final part of this Tralfamadorian Odyssey, qkfzca has invited you to the sesquicentennial Tralfamadorian Trivia Night.

    qkfzca seems a little animated, although it is hard to tell. She tells you it’s the favorite event of her lifetime.

    qkfzca : “Absolutely everybody gets a little something.”

    She promises you that the abduction will come to an end once you complete the Trivia.

    Feel free to utilize Office Hours for any questions about this section. Although help will be provided through Piazza, it will help your intuition in understanding git if explained in person!

    Git Parable: Collaboration

    One of the benefits of using git is the ability to collaborate. So far, we’ve been using your local git repository to keep track of your workflow.

    By having a remote shared repository, you can share your snapshots with others.

    In this next exercise, you will have a chance to create a GitHub repository and solve some Trivia with a partner.

    Task 1: Another Earthling

    You must find an Earthling partner (enrolled in CS 2043) for the Trivia. You may use Piazza’s partner finding functionality.

    Tralfamadorian partners also accepted, if found.

    Task 2: Solve Your Trivia

    Solve the questions under the part3 directory on your own. Correctness of your solutions does not matter for the Trivia (but is good for your soul).

    Task 3: Merge time!

    Create a new GitHub repository through the CornellCIS GitHub.

    Place the created git repository under your part3 directory (git clone <git-repository-url> may help).

    In order to complete the Trivia, you must succeed in the following things:

    Note: In order to successfully follow these steps, exactly one person should initialize the GitHub repository and push a commit to it, then the next person should clone the repository and push a commit.

    WARNING: do not use git rebase for the purposes of this assignment.

    Git Parable: Collaboration and Merging

    At the end of this assignment, you should have a complete snapshot (your partner and yours) of your Trivia (check git log).

    Through git, you can merge two separate branches of development into a single snapshot. Once you complete a merge, and all partners fetch all the snapshots from the master branch (git pull), both of your histories (git log) should match exactly.

    As you’re preparing to leave, qkfzca has something to say.

    qkfzca : “Everything was beautiful and nothing hurt.”

    Once you’re done with Part 3, follow these instructions for submission

    1. git clone your repo onto wash, onto your ~/Desktop. This must be a fresh clone.
    2. run handin vonne-git-3 <git-repo-directory>. For instance, if your git clone-ing your GitHub repository created a directory Trivia/, run handin vonne-git-3 Trivia/.
    Poo-tee-weet?

    Congratulations! You have successfully escaped Tralfamadore.

    Now that you’re back on Earth, you realize it’s springtime. Birds are talking.

    One bird says to you, ‘Poo-tee-weet?’

    CS 2043 Assignment 4: The Fellowship of the Script

    Due Date: Friday February 22 at 11:15 AM

    Assignment Captains Ashneel Das, Chris Roman

    In this assignment, we will be writing more advanced scripts through a Lord of the Rings themed story. If you would like a de-themed version of the assignment, please go here.

    Frodo sits quietly reading a book in the forest, dreaming of the day when Gandalf will return with some more fireworks. More importantly, though, he grows weary of looking after the increasingly frustrating senility of Bilbo. Unbeknownst to Bilbo, Frodo, and even Gandalf, though, treachery is afoot. As it turns out, the great Base Master of Treachery (Sauron) really engineered the rings of power to siphon intellect from the wearer of the ring. He wanted to live forever, but was well versed in the unfortunate truth of how the brain ages and realized he could steal the ring-bearer’s marbles for himself.

    Task 1

    Note: You will be appending to two files, MARBLES.txt and FAILED.log, in this task.

    Frodo’s least favorite task of the day is helping Bilbo find his marbles. All the old fool does day in and day out is shut himself in his study and re-read is various maps and journals, muttering on about how if he could only find his marbles then he could return to live with the Elves. The only thing that Frodo hates more than “helping” Bilbo find his marbles is playing the “What’s in my Pocket game”, because the answer is always the same.

    Each day between Elevenses and Lunch Bilbo demands that Frodo assist in the age-old task of the marble search. Having been traumatized by this search everyday since the time he could walk, Frodo has finally decided that he should automate the process. According to Bilbo, he has encoded the secret location of the marbles in different maps and journals throughout his study. However, these maps and journals were actually given to him by the Elves (who stole them from Dwarves), and it is futile to search for marbles on the wrong day of the year.

    Each day Bilbo recites a list of maps and journals that are valid to search on that day from memory, and Frodo must collect them all and search for the marbles. Bilbo also informs Frodo that there is a minimum and maximum line-length (specific to that day) that would potentially contain the location of a given marble. That is, as Frodo reads through every line of the journals and maps, if a given line of prose contains fewer words than the dictated minimum, or more words than the dictated maximum, then no marbles have been described by that line and Frodo should move on.

    Create a script named collect_marbles.sh in the TASK_1 directory that performs the following:

    1. The script will be called with arguments as follows:
      • The “length” of a line is defined as the number of words on the line.
      • The first argument is the minimum length of a line.
      • The second argument is the maximum length of a line.
      • All remaining arguments are the names of the journals and maps that are to be searched (filenames). There is no limit to the number of additional arguments.
    2. If your script receives fewer than 3 arguments, it should print the exact message to STDERR:

       Ye shall not search for marbles if ye cannot find the key.
      

      and produce an exit code of 64, without doing any further processing. AKA check for this at the beginning before doing anything else… In order to redirect to STDERR, you can type >&2 echo "error". This means you are redirecting the output of echo (in this case, “error”) to file descriptor 2. In the world of UNIX, file descriptor 2 represents STDERR, whereas file descriptor 1 represents STDOUT.

    3. You may assume that arguments one and two, if supplied, are positive integers where:
      • The minimum length is greater than or equal to 1.
      • The maximum length is greater than or equal to the minimum length (never less than).
    4. You may not assume that the third and higher arguments are valid. That is, you must verify that the argument given is a file you can read first before trying to process it.
      • If an argument given is not a real file, append the name that was given to FAILED.log in the current directory.
    5. For every valid file path specified, loop over every line in the file:
      • Count the number of words on that line. A word is defined as anything separated by a space.
      • If the number of words is between the minimum and maximum that Bilbo specified, append it to the end of MARBLES.txt in the current directory.
      • Otherwise, just move on to the next line.

    Warning: for full credit, TASK_1/collect_marbles.sh must be executable.

    Once you are done, hand in the assignment using handin fellowship-1 collect_marbles.sh

    Sample Inputs and Output

    Refer to TASK_1/TASK_1_EXAMPLE.md.

    Task 2

    Frodo can at long last enjoy a little bit of “me-time”, as Bilbo refuses to allow Frodo to be involved in the decryption phase. Somewhat agitated by the fact that Bilbo will not allow him to partake in this task after all these years, Frodo decides to return to the forest to catch up on some reading. After all, he doesn’t really even want to be involved in that part…Bilbo claims that marble decryption must be done whilst wearing a tea cosy on your head and nothing else.

    As Frodo tries to forget that mental image, he is knocked over by Pippin and Merry who seem to have come out of nowhere. It becomes quite apparent that not only have they been stealing crops from Farmer Maggot, but they have been stealing his marbles too! They realized that the more marbles they steal from Farmer Maggot, the easier it is to steal crops (since they are effectively degrading his consciousness).

    Intrigued by the idea, and appalled by the act, Frodo is now entrenched in an awkward situation. Pippin and Merry somehow already found out that Frodo is a total Unix scripting pro, and have asked him to help them create a tool that would enable them to analyze their potential profits from both the crops and the marbles.

    Frodo realizes that they are too foolish to connect the dots that if they would only eat the marbles they could write their own, and strikes a deal: he will create this tool for them if they pay him with the marbles they have stolen. He convinces them that once removed they are useless, and that they can only make a profit from the crops anyway.

    They are suspicious, but Frodo explains that he is going to try and use them to satiate Bilbo’s ludicrous marble search. Having grown up with Frodo, they accept this as a plausible application.


    You are to create a script merry_math.sh in the TASK_2 directory that can analyze specific columns of a csv file. A csv file is a “Comma Separated Value” sheet often used for storing data such as the number of carrots or potatoes stolen on a given day. Ordinarily csv files are supposed to have the first row be the “Header”, that describes what each column is. For this task, there will be no header to simplify your work. There will also be no quotes or other strange characters you need to worry about. Just assume it will be plain text separated by commas.


    Your script must support the following integer arithmetic operations:


    Your script will receive input arguments in the following form:

    To be extra clear, you should check errors in the following order to provide the correct error code priorities:

    if too few arguments, then
        exit with an error code of 64
    else if the provided filename is not a file, then
        exit with an error code of 66
    else if the operation code provided is not supported, then
        exit with an error code of 69
    

    So if four arguments were provided, but both the filename and operation code were invalid, then the exit code should be 66, not 69.


    Your script is to strip the columns requested and perform the mathematical operation requested.

    Warning: for full credit, TASK_2/merry_math.sh must be executable.

    Once you are done, hand in the assignment using handin fellowship-2 merry_math.sh

    Sample Inputs and Output

    Refer to TASK_2/TASK_2_EXAMPLE.md.

    Task 3

    Enthralled by the superb automation he is now able to perform, Frodo ponders what could possibly be next. As Pippin and Merry go skipping away contented with their new calculator, Frodo hears a faint but familiar song being hummed off in the distance. Taken aback by the comforting melody, he decides to go track down who could possibly be such a talented songster. For not only is there humming, but a unique form of whistling that he suspects would summon even the most regal and renowned of horses.

    Frolicking through the forest, he comes to a road just as Gandalf the Omnipotently Nonchalant rides his carriage toward the Shire. Unable to contain his joy (because this almost certainly means there will be fireworks), he leaps from the side of the road onto Gandalf’s cart. Gandalf laughs in a manner that makes Frodo think there may be some marbles missing from Gandalf as well, but dares not to ask.

    As they ride in to town, Gandalf turns to Frodo and inquires whether he might be interested in helping him con Sauron. For too many years Gandalf has been overshadowed by him, and seeks the title of Great Deceiver, but he is far too old to learn how to use computers and needs help designing a website. Gandalf was able to convince Sam to create a Markdown document for the website in exchange for some potatoes, but despite great efforts Sam was simply just too simple to be able to create anything more interesting.

    Gandalf is confident that he will need a colorful website in order to pull off this scandal, and turns to Frodo. Having learned of his recent super-pro-allstar status as a Unix guru, Gandalf is confident that Frodo will be able to provide a tool that can take any one of the the Markdown documents Sam completes and generate a colorful HTML page.

    Gandalf scurries away claiming that there are questions, questions that need answering, and Frodo is left to himself to complete the task alone (once again). Intimidated by sed, Frodo gobbles down his newly acquired Maggot-Marbles and instantly feels ready to complete his next task.

    You are to write the script gandalfify.sh in the TASK_3 directory to be a relatively basic Markdown to HTML parser. You will need to utilize sed to complete this task. You do not need to understand the syntax of Markdown or HTML in order to complete this task – just follow the directions and it will work. I have chosen to give you this assignment because it gives you visual confirmation that you have been successful.

    Before enumerating the tasks explicitly, I must describe some BSD vs GNU compatibility issues.


    Forbidden Behavior:

    Under no circumstances are you allowed to use the -i flag for sed. If you use it, you will receive 0 points. It is not portable, and you should have no reason to use it.


    Required Behavior:

    You will likely want to to use extended regular expressions for this task. The + operator (which means find one or more of the expression it modifies), for example, is part of the extended regular expressions. For example, the regex [a-z]+ simply denotes “one or more lowercase letter”. Strings that are in this set would be things like a, asdf, fdsa, etc.

    GNU sed uses the -r flag to indicate that extended regular expressions are permitted, whereas the BSD (and therefore OSX) sed uses the -E (capital, not lower case!) flag to enable these. However, as it turns out, even though the -E flag is not present in the GNU man sed page, it is supported and is exactly the same as -r.


    Task 3.1: Generate the Paragraphs (<p> tags) for HTML

    You should assume that any line that has text, but does not start with a # sign will turn into a paragraph. In Markdown, you can create headers (title sections) by starting the line with a # and writing the title afterward. For example, these are all valid Markdown headers:

    # This is an H1 header
    
    This is a regular paragraph.
    
    ##          This is an H2 header
    
    This is another regular paragraph.
    
    ###    This is an H3 header.
    
    This is yet another regular paragraph.
    

    Note that there is an arbitrary amount of whitespace (that is not a newline) before the headers. We will account for this in task 3.2. A friendly reminder of some things that might be useful:

    As in class, we discussed how to only do replacements with sed if the line starts with a certain regex. This command only checks lines beginning with “The”:

    sed '/^The/s/john/John/g' file
    

    What we haven’t discussed is how to check lines that don’t begin with “The”, which is done as follows:

    sed '/^The/!s/john/John/g' file
    

    For this task, you need to surround the regular paragraphs with the HTML paragraph tag. In HTML, you start a tag with <tag>, and end it with </tag> (where the ending has a /). The paragraph tag is p. So for example, you would take the line

       This is a regular paragraph.
    

    and turn it into

       <p>This is a regular paragraph.</p>
    

    For simplicity, you can assume that there will not be any preceding whitespace before the text you are to turn into a paragraph. So you will not have to account for something like

           This is a weird paragraph with preceding whitespace.
    

    Go ahead and get started!

    Task 3.2: Generate the Headers for HTML

    At this point we now have all of our paragraphs accounted for, and can start turning the various levels of # into the appropriate header. You will need to account for only the cases in which you have 1, 2, or 3 #s, corresponding to <h1>, <h2>, and <h3> respectively.

    Working with the example we started above, our text now looks something like this:

    # This is an H1 header
    
    <p>This is a regular paragraph.</p>
    
    ##          This is an H2 header
    
    <p>This is another regular paragraph.</p>
    
    ###    This is an H3 header.
    
    <p>This is yet another regular paragraph.</p>
    

    You need to produce

    <h1>This is an H1 header</h1>
    
    <p>This is a regular paragraph.</p>
    
    <h2>This is an H2 header</h2>
    
    <p>This is another regular paragraph.</p>
    
    <h3>This is an H3 header.</h3>
    
    <p>This is yet another regular paragraph.</p>
    

    Warning:

    1. Note that I have removed the whitespace between the # and the text. You must do the same.

    2. The whitespace in MARBLE_SHOPPE.md has a mixture of spaces and tabs in some cases. You must catch these.
      • Use the POSIX sets.
    3. Note: Lines with no whitespace between the “#” and text should still be converted to headers.

      ##Header 2 with no whitespace must be parsed correctly
      

    should be

       <h2>Header 2 with no whitespace must be parsed correctly</h2>
    

    Using the Script

    The gandalfify.sh script expects exactly one argument: the name of the Markdown document file to be parsed / turned into an HTML document. Simply specify the name of the file you want to parse. For example, assuming you were in the a4/TASK_3 directory:

    $ ./gandalfify.sh MARBLE_SHOPPE.md
    Converted MARBLE_SHOPPE.md into index.html!
    

    From there, you can “visually debug” by simply opening index.html in your browser. The cool thing is you can keep it open in the browser, and re-run the script and then just refresh your browser to see the updated version :)

    From there, if you would like to “visually debug”, you may use SCP to transfer the HTML file to your local computer and open index.html in your browser.

    Once you are done, hand in the assignment using handin fellowship-3 gandalfify.sh

    Sample Input and Output

    Refer to TASK_3/TASK_3_EXAMPLE.md.

    Challenge Questions (optional - we will not grade this, but you might find it fun!)

    1. Produce proper indentation automatically using sed.
    2. There is an un-ordered list in MARBLE_SHOPPE.md, but each element will get parsed into a separate paragraph. Turn them into HTML unordered lists.

      Unordered lists in Markdown come in a variety of forms:

      + one format uses plus signs
      + to indicate new bullets
      + in the list
      
      - one format uses hyphens
      - to indicate new bullets
      - in the list
      
      * one format uses plus asterisks
      * to indicate new bullets
      * in the list
      

      They are all equivalent, and you can assume that I will not mix them (+ and - for example, will not be used in the same list).

      The HTML unordered list is as follows:

      <ul>
          <li>This is an item.</li>
          <li>This is another item.</li>
          <li>This is the last item.</li>
      </ul>
      

      So you will not only need to surround each bullet from Markdown in an li tag, but you will have to be able to find the beginning and end of the list and put the ul tag. You should assume that there will not be any newlines between bullet points. For example:

      - This list is acceptable
      - Because it is
      - Formatted correctly
      - Yay!
      

      whereas

      - This list will end up as two separate lists
      - Because there is an empty line between them
      
      - And your regex will see this as the end of the list
      - ...most likely.