diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index 57737a615fc..00000000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: MarkBind Action - -on: - push: - branches: - - master - -jobs: - build_and_deploy: - runs-on: ubuntu-latest - steps: - - name: Install Graphviz - run: sudo apt-get install graphviz - - name: Install Java - uses: actions/setup-java@v3 - with: - java-version: '11' - distribution: 'temurin' - - name: Build & Deploy MarkBind site - uses: MarkBind/markbind-action@v2 - with: - token: ${{ secrets.GITHUB_TOKEN }} - rootDirectory: './docs' - baseUrl: '/addressbook-level3' # replace with your repo name - version: '^5.1.0' diff --git a/.gitignore b/.gitignore index f99a4d436a8..722d372133c 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,3 @@ src/test/data/sandbox/ # MacOS custom attributes files created by Finder .DS_Store docs/_site/ -docs/_markbind/logs/ diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 1748e487fbd..00000000000 --- a/docs/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -_markbind/logs/ - -# Dependency directories -node_modules/ - -# Production build files (change if you output the build to a different directory) -_site/ - -# Env -.env -.env.local - -# IDE configs -.vscode/ -.idea/* -*.iml diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 8cf4ab68e9e..1c9514e966a 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,10 +1,8 @@ --- - layout: default.md - title: "About Us" +layout: page +title: About Us --- -# About Us - We are a team based in the [School of Computing, National University of Singapore](http://www.comp.nus.edu.sg). You can reach us at the email `seer[at]comp.nus.edu.sg` diff --git a/docs/Configuration.md b/docs/Configuration.md index 32f6255f3b9..13cf0faea16 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -1,8 +1,6 @@ --- - layout: default.md - title: "Configuration guide" +layout: page +title: Configuration guide --- -# Configuration guide - Certain properties of the application can be controlled (e.g user preferences file location, logging level) through the configuration file (default: `config.json`). diff --git a/docs/DevOps.md b/docs/DevOps.md index 8228c845e86..d2fd91a6001 100644 --- a/docs/DevOps.md +++ b/docs/DevOps.md @@ -1,15 +1,12 @@ --- - layout: default.md - title: "DevOps guide" - pageNav: 3 +layout: page +title: DevOps guide --- -# DevOps guide +* Table of Contents +{:toc} - - - - +-------------------------------------------------------------------------------------------------------------------- ## Build automation diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index a5a11185ae1..8a861859bfd 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,19 +1,15 @@ --- - layout: default.md - title: "Developer Guide" - pageNav: 3 +layout: page +title: Developer Guide --- - -# AB-3 Developer Guide - - - +* Table of Contents +{:toc} -------------------------------------------------------------------------------------------------------------------- ## **Acknowledgements** -_{ list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well }_ +* {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} -------------------------------------------------------------------------------------------------------------------- @@ -25,9 +21,14 @@ Refer to the guide [_Setting up and getting started_](SettingUp.md). ## **Design** +
+ +:bulb: **Tip:** The `.puml` files used to create diagrams in this document `docs/diagrams` folder. Refer to the [_PlantUML Tutorial_ at se-edu/guides](https://se-education.org/guides/tutorials/plantUml.html) to learn how to create and edit diagrams. +
+ ### Architecture - + The ***Architecture Diagram*** given above explains the high-level design of the App. @@ -52,7 +53,7 @@ The bulk of the app's work is done by the following four components: The *Sequence Diagram* below shows how the components interact with each other for the scenario where the user issues the command `delete 1`. - + Each of the four main components (also shown in the diagram above), @@ -61,7 +62,7 @@ Each of the four main components (also shown in the diagram above), For example, the `Logic` component defines its API in the `Logic.java` interface and implements its functionality using the `LogicManager.java` class which follows the `Logic` interface. Other components interact with a given component through its interface rather than the concrete class (reason: to prevent outside component's being coupled to the implementation of a component), as illustrated in the (partial) class diagram below. - + The sections below give more details of each component. @@ -69,7 +70,7 @@ The sections below give more details of each component. The **API** of this component is specified in [`Ui.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/ui/Ui.java) - +![Structure of the UI Component](images/UiClassDiagram.png) The UI consists of a `MainWindow` that is made up of parts e.g.`CommandBox`, `ResultDisplay`, `PersonListPanel`, `StatusBarFooter` etc. All these, including the `MainWindow`, inherit from the abstract `UiPart` class which captures the commonalities between classes that represent parts of the visible GUI. @@ -88,16 +89,14 @@ The `UI` component, Here's a (partial) class diagram of the `Logic` component: - + The sequence diagram below illustrates the interactions within the `Logic` component, taking `execute("delete 1")` API call as an example. - - - +![Interactions Inside the Logic Component for the `delete 1` Command](images/DeleteSequenceDiagram.png) -**Note:** The lifeline for `DeleteCommandParser` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. - +
:information_source: **Note:** The lifeline for `DeleteCommandParser` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. +
How the `Logic` component works: @@ -108,7 +107,7 @@ How the `Logic` component works: Here are the other classes in `Logic` (omitted from the class diagram above) that are used for parsing a user command: - + How the parsing works: * When called upon to parse a user command, the `AddressBookParser` class creates an `XYZCommandParser` (`XYZ` is a placeholder for the specific command name e.g., `AddCommandParser`) which uses the other classes shown above to parse the user command and create a `XYZCommand` object (e.g., `AddCommand`) which the `AddressBookParser` returns back as a `Command` object. @@ -117,7 +116,7 @@ How the parsing works: ### Model component **API** : [`Model.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/model/Model.java) - + The `Model` component, @@ -127,20 +126,18 @@ The `Model` component, * stores a `UserPref` object that represents the user’s preferences. This is exposed to the outside as a `ReadOnlyUserPref` objects. * does not depend on any of the other three components (as the `Model` represents data entities of the domain, they should make sense on their own without depending on other components) - - -**Note:** An alternative (arguably, a more OOP) model is given below. It has a `Tag` list in the `AddressBook`, which `Person` references. This allows `AddressBook` to only require one `Tag` object per unique tag, instead of each `Person` needing their own `Tag` objects.
+
:information_source: **Note:** An alternative (arguably, a more OOP) model is given below. It has a `Tag` list in the `AddressBook`, which `Person` references. This allows `AddressBook` to only require one `Tag` object per unique tag, instead of each `Person` needing their own `Tag` objects.
- + - +
### Storage component **API** : [`Storage.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/storage/Storage.java) - + The `Storage` component, * can save both address book data and user preference data in JSON format, and read them back into corresponding objects. @@ -173,63 +170,54 @@ Given below is an example usage scenario and how the undo/redo mechanism behaves Step 1. The user launches the application for the first time. The `VersionedAddressBook` will be initialized with the initial address book state, and the `currentStatePointer` pointing to that single address book state. - +![UndoRedoState0](images/UndoRedoState0.png) Step 2. The user executes `delete 5` command to delete the 5th person in the address book. The `delete` command calls `Model#commitAddressBook()`, causing the modified state of the address book after the `delete 5` command executes to be saved in the `addressBookStateList`, and the `currentStatePointer` is shifted to the newly inserted address book state. - +![UndoRedoState1](images/UndoRedoState1.png) Step 3. The user executes `add n/David …​` to add a new person. The `add` command also calls `Model#commitAddressBook()`, causing another modified address book state to be saved into the `addressBookStateList`. - +![UndoRedoState2](images/UndoRedoState2.png) - +
:information_source: **Note:** If a command fails its execution, it will not call `Model#commitAddressBook()`, so the address book state will not be saved into the `addressBookStateList`. -**Note:** If a command fails its execution, it will not call `Model#commitAddressBook()`, so the address book state will not be saved into the `addressBookStateList`. - - +
Step 4. The user now decides that adding the person was a mistake, and decides to undo that action by executing the `undo` command. The `undo` command will call `Model#undoAddressBook()`, which will shift the `currentStatePointer` once to the left, pointing it to the previous address book state, and restores the address book to that state. - - - - +![UndoRedoState3](images/UndoRedoState3.png) -**Note:** If the `currentStatePointer` is at index 0, pointing to the initial AddressBook state, then there are no previous AddressBook states to restore. The `undo` command uses `Model#canUndoAddressBook()` to check if this is the case. If so, it will return an error to the user rather +
:information_source: **Note:** If the `currentStatePointer` is at index 0, pointing to the initial AddressBook state, then there are no previous AddressBook states to restore. The `undo` command uses `Model#canUndoAddressBook()` to check if this is the case. If so, it will return an error to the user rather than attempting to perform the undo. - +
The following sequence diagram shows how the undo operation works: - +![UndoSequenceDiagram](images/UndoSequenceDiagram.png) - +
:information_source: **Note:** The lifeline for `UndoCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. -**Note:** The lifeline for `UndoCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. - - +
The `redo` command does the opposite — it calls `Model#redoAddressBook()`, which shifts the `currentStatePointer` once to the right, pointing to the previously undone state, and restores the address book to that state. - - -**Note:** If the `currentStatePointer` is at index `addressBookStateList.size() - 1`, pointing to the latest address book state, then there are no undone AddressBook states to restore. The `redo` command uses `Model#canRedoAddressBook()` to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo. +
:information_source: **Note:** If the `currentStatePointer` is at index `addressBookStateList.size() - 1`, pointing to the latest address book state, then there are no undone AddressBook states to restore. The `redo` command uses `Model#canRedoAddressBook()` to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo. - +
Step 5. The user then decides to execute the command `list`. Commands that do not modify the address book, such as `list`, will usually not call `Model#commitAddressBook()`, `Model#undoAddressBook()` or `Model#redoAddressBook()`. Thus, the `addressBookStateList` remains unchanged. - +![UndoRedoState4](images/UndoRedoState4.png) Step 6. The user executes `clear`, which calls `Model#commitAddressBook()`. Since the `currentStatePointer` is not pointing at the end of the `addressBookStateList`, all address book states after the `currentStatePointer` will be purged. Reason: It no longer makes sense to redo the `add n/David …​` command. This is the behavior that most modern desktop applications follow. - +![UndoRedoState5](images/UndoRedoState5.png) The following activity diagram summarizes what happens when a user executes a new command: - + #### Design considerations: @@ -282,14 +270,14 @@ _{Explain here how the data archiving feature will be implemented}_ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*` -| Priority | As a …​ | I want to …​ | So that I can…​ | -|----------|--------------------------------------------|------------------------------|------------------------------------------------------------------------| -| `* * *` | new user | see usage instructions | refer to instructions when I forget how to use the App | -| `* * *` | user | add a new person | | -| `* * *` | user | delete a person | remove entries that I no longer need | -| `* * *` | user | find a person by name | locate details of persons without having to go through the entire list | -| `* *` | user | hide private contact details | minimize chance of someone else seeing them by accident | -| `*` | user with many persons in the address book | sort persons by name | locate a person easily | +| Priority | As a …​ | I want to …​ | So that I can…​ | +| -------- | ------------------------------------------ | ------------------------------ | ---------------------------------------------------------------------- | +| `* * *` | new user | see usage instructions | refer to instructions when I forget how to use the App | +| `* * *` | user | add a new person | | +| `* * *` | user | delete a person | remove entries that I no longer need | +| `* * *` | user | find a person by name | locate details of persons without having to go through the entire list | +| `* *` | user | hide private contact details | minimize chance of someone else seeing them by accident | +| `*` | user with many persons in the address book | sort persons by name | locate a person easily | *{More to be added}* @@ -341,12 +329,10 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli Given below are instructions to test the app manually. - - -**Note:** These instructions only provide a starting point for testers to work on; +
:information_source: **Note:** These instructions only provide a starting point for testers to work on; testers are expected to do more *exploratory* testing. - +
### Launch and shutdown diff --git a/docs/Documentation.md b/docs/Documentation.md index 082e652d947..3e68ea364e7 100644 --- a/docs/Documentation.md +++ b/docs/Documentation.md @@ -1,21 +1,29 @@ --- - layout: default.md - title: "Documentation guide" - pageNav: 3 +layout: page +title: Documentation guide --- -# Documentation Guide +**Setting up and maintaining the project website:** + +* We use [**Jekyll**](https://jekyllrb.com/) to manage documentation. +* The `docs/` folder is used for documentation. +* To learn how set it up and maintain the project website, follow the guide [_[se-edu/guides] **Using Jekyll for project documentation**_](https://se-education.org/guides/tutorials/jekyll.html). +* Note these points when adapting the documentation to a different project/product: + * The 'Site-wide settings' section of the page linked above has information on how to update site-wide elements such as the top navigation bar. + * :bulb: In addition to updating content files, you might have to update the config files `docs\_config.yml` and `docs\_sass\minima\_base.scss` (which contains a reference to `AB-3` that comes into play when converting documentation pages to PDF format). +* If you are using Intellij for editing documentation files, you can consider enabling 'soft wrapping' for `*.md` files, as explained in [_[se-edu/guides] **Intellij IDEA: Useful settings**_](https://se-education.org/guides/tutorials/intellijUsefulSettings.html#enabling-soft-wrapping) -* We use [**MarkBind**](https://markbind.org/) to manage documentation. -* The `docs/` folder contains the source files for the documentation website. -* To learn how set it up and maintain the project website, follow the guide [[se-edu/guides] Working with Forked MarkBind sites](https://se-education.org/guides/tutorials/markbind-forked-sites.html) for project documentation. **Style guidance:** * Follow the [**_Google developer documentation style guide_**](https://developers.google.com/style). -* Also relevant is the [_se-edu/guides **Markdown coding standard**_](https://se-education.org/guides/conventions/markdown.html). +* Also relevant is the [_[se-edu/guides] **Markdown coding standard**_](https://se-education.org/guides/conventions/markdown.html) + +**Diagrams:** + +* See the [_[se-edu/guides] **Using PlantUML**_](https://se-education.org/guides/tutorials/plantUml.html) -**Converting to PDF** +**Converting a document to the PDF format:** -* See the guide [_se-edu/guides **Saving web documents as PDF files**_](https://se-education.org/guides/tutorials/savingPdf.html). +* See the guide [_[se-edu/guides] **Saving web documents as PDF files**_](https://se-education.org/guides/tutorials/savingPdf.html) diff --git a/docs/Gemfile b/docs/Gemfile new file mode 100644 index 00000000000..c8385d85874 --- /dev/null +++ b/docs/Gemfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } + +gem 'jekyll' +gem 'github-pages', group: :jekyll_plugins +gem 'wdm', '~> 0.1.0' if Gem.win_platform? +gem 'webrick' diff --git a/docs/Logging.md b/docs/Logging.md index 589644ad5c6..5e4fb9bc217 100644 --- a/docs/Logging.md +++ b/docs/Logging.md @@ -1,10 +1,8 @@ --- - layout: default.md - title: "Logging guide" +layout: page +title: Logging guide --- -# Logging guide - * We are using `java.util.logging` package for logging. * The `LogsCenter` class is used to manage the logging levels and logging destinations. * The `Logger` for a class can be obtained using `LogsCenter.getLogger(Class)` which will log messages according to the specified logging level. diff --git a/docs/SettingUp.md b/docs/SettingUp.md index 03df0295bd2..275445bd551 100644 --- a/docs/SettingUp.md +++ b/docs/SettingUp.md @@ -1,32 +1,27 @@ --- - layout: default.md - title: "Setting up and getting started" - pageNav: 3 +layout: page +title: Setting up and getting started --- -# Setting up and getting started +* Table of Contents +{:toc} - - -------------------------------------------------------------------------------------------------------------------- ## Setting up the project in your computer - +
:exclamation: **Caution:** -**Caution:** Follow the steps in the following guide precisely. Things will not work out if you deviate in some steps. - +
First, **fork** this repo, and **clone** the fork into your computer. If you plan to use Intellij IDEA (highly recommended): 1. **Configure the JDK**: Follow the guide [_[se-edu/guides] IDEA: Configuring the JDK_](https://se-education.org/guides/tutorials/intellijJdk.html) to to ensure Intellij is configured to use **JDK 11**. -1. **Import the project as a Gradle project**: Follow the guide [_[se-edu/guides] IDEA: Importing a Gradle project_](https://se-education.org/guides/tutorials/intellijImportGradleProject.html) to import the project into IDEA. - - Note: Importing a Gradle project is slightly different from importing a normal Java project. - +1. **Import the project as a Gradle project**: Follow the guide [_[se-edu/guides] IDEA: Importing a Gradle project_](https://se-education.org/guides/tutorials/intellijImportGradleProject.html) to import the project into IDEA.
+ :exclamation: Note: Importing a Gradle project is slightly different from importing a normal Java project. 1. **Verify the setup**: 1. Run the `seedu.address.Main` and try a few commands. 1. [Run the tests](Testing.md) to ensure they all pass. @@ -39,11 +34,10 @@ If you plan to use Intellij IDEA (highly recommended): If using IDEA, follow the guide [_[se-edu/guides] IDEA: Configuring the code style_](https://se-education.org/guides/tutorials/intellijCodeStyle.html) to set up IDEA's coding style to match ours. - +
:bulb: **Tip:** - **Tip:** Optionally, you can follow the guide [_[se-edu/guides] Using Checkstyle_](https://se-education.org/guides/tutorials/checkstyle.html) to find how to use the CheckStyle within IDEA e.g., to report problems _as_ you write code. - +
1. **Set up CI** diff --git a/docs/Testing.md b/docs/Testing.md index 78ddc57e670..8a99e82438a 100644 --- a/docs/Testing.md +++ b/docs/Testing.md @@ -1,15 +1,12 @@ --- - layout: default.md - title: "Testing guide" - pageNav: 3 +layout: page +title: Testing guide --- -# Testing guide +* Table of Contents +{:toc} - - - - +-------------------------------------------------------------------------------------------------------------------- ## Running tests @@ -22,10 +19,8 @@ There are two ways to run tests. * **Method 2: Using Gradle** * Open a console and run the command `gradlew clean test` (Mac/Linux: `./gradlew clean test`) - - -**Link**: Read [this Gradle Tutorial from the se-edu/guides](https://se-education.org/guides/tutorials/gradle.html) to learn more about using Gradle. - +
:link: **Link**: Read [this Gradle Tutorial from the se-edu/guides](https://se-education.org/guides/tutorials/gradle.html) to learn more about using Gradle. +
-------------------------------------------------------------------------------------------------------------------- diff --git a/docs/UserGuide.md b/docs/UserGuide.md index b3abf0e8722..57437026c7b 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -1,15 +1,12 @@ --- - layout: default.md - title: "User Guide" - pageNav: 3 +layout: page +title: User Guide --- -# AB-3 User Guide +AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized for use via a Command Line Interface** (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, AB3 can get your contact management tasks done faster than traditional GUI apps. -AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized for use via a Line Interface** (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, AB3 can get your contact management tasks done faster than traditional GUI apps. - - - +* Table of Contents +{:toc} -------------------------------------------------------------------------------------------------------------------- @@ -44,9 +41,9 @@ AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized fo ## Features - +
-**Notes about the command format:**
+**:information_source: Notes about the command format:**
* Words in `UPPER_CASE` are the parameters to be supplied by the user.
e.g. in `add n/NAME`, `NAME` is a parameter which can be used as `add n/John Doe`. @@ -64,7 +61,7 @@ AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized fo e.g. if the command specifies `help 123`, it will be interpreted as `help`. * If you are using a PDF version of this document, be careful when copying and pasting commands that span multiple lines as space characters surrounding line-breaks may be omitted when copied over to the application. - +
### Viewing help : `help` @@ -81,10 +78,9 @@ Adds a person to the address book. Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​` - - -**Tip:** A person can have any number of tags (including 0) - +
:bulb: **Tip:** +A person can have any number of tags (including 0) +
Examples: * `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` @@ -165,11 +161,9 @@ AddressBook data are saved in the hard disk automatically after any command that AddressBook data are saved automatically as a JSON file `[JAR file location]/data/addressbook.json`. Advanced users are welcome to update data directly by editing that data file. - - -**Caution:** -If your changes to the data file makes its format invalid, AddressBook will discard all data and start with an empty data file at the next run. Hence, it is recommended to take a backup of the file before editing it. - +
:exclamation: **Caution:** +If your changes to the data file makes its format invalid, AddressBook will discard all data and start with an empty data file at the next run. Hence, it is recommended to take a backup of the file before editing it. +
### Archiving data files `[coming in v2.0]` @@ -192,12 +186,12 @@ _Details coming soon ..._ ## Command summary -Action | Format, Examples ------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------- -**Add** | `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​`
e.g., `add n/James Ho p/22224444 e/jamesho@example.com a/123, Clementi Rd, 1234665 t/friend t/colleague` -**Clear** | `clear` +Action | Format, Examples +--------|------------------ +**Add** | `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​`
e.g., `add n/James Ho p/22224444 e/jamesho@example.com a/123, Clementi Rd, 1234665 t/friend t/colleague` +**Clear** | `clear` **Delete** | `delete INDEX`
e.g., `delete 3` -**Edit** | `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG]…​`
e.g.,`edit 2 n/James Lee e/jameslee@example.com` -**Find** | `find KEYWORD [MORE_KEYWORDS]`
e.g., `find James Jake` -**List** | `list` -**Help** | `help` +**Edit** | `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG]…​`
e.g.,`edit 2 n/James Lee e/jameslee@example.com` +**Find** | `find KEYWORD [MORE_KEYWORDS]`
e.g., `find James Jake` +**List** | `list` +**Help** | `help` diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 00000000000..6bd245d8f4e --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,15 @@ +title: "AB-3" +theme: minima + +header_pages: + - UserGuide.md + - DeveloperGuide.md + - AboutUs.md + +markdown: kramdown + +repository: "se-edu/addressbook-level3" +github_icon: "images/github-icon.png" + +plugins: + - jemoji diff --git a/docs/_data/projects.yml b/docs/_data/projects.yml new file mode 100644 index 00000000000..8f3e50cb601 --- /dev/null +++ b/docs/_data/projects.yml @@ -0,0 +1,23 @@ +- name: "AB-1" + url: https://se-edu.github.io/addressbook-level1 + +- name: "AB-2" + url: https://se-edu.github.io/addressbook-level2 + +- name: "AB-3" + url: https://se-edu.github.io/addressbook-level3 + +- name: "AB-4" + url: https://se-edu.github.io/addressbook-level4 + +- name: "Duke" + url: https://se-edu.github.io/duke + +- name: "Collate" + url: https://se-edu.github.io/collate + +- name: "Book" + url: https://se-edu.github.io/se-book + +- name: "Resources" + url: https://se-edu.github.io/resources diff --git a/docs/_includes/custom-head.html b/docs/_includes/custom-head.html new file mode 100644 index 00000000000..8559a67ffad --- /dev/null +++ b/docs/_includes/custom-head.html @@ -0,0 +1,6 @@ +{% comment %} + Placeholder to allow defining custom head, in principle, you can add anything here, e.g. favicons: + + 1. Head over to https://realfavicongenerator.net/ to add your own favicons. + 2. Customize default _includes/custom-head.html in your source directory and insert the given code snippet. +{% endcomment %} diff --git a/docs/_includes/head.html b/docs/_includes/head.html new file mode 100644 index 00000000000..83ac5326933 --- /dev/null +++ b/docs/_includes/head.html @@ -0,0 +1,12 @@ + + + + + + + + {%- include custom-head.html -%} + + {{page.title}} + + diff --git a/docs/_includes/header.html b/docs/_includes/header.html new file mode 100644 index 00000000000..33badcd4f99 --- /dev/null +++ b/docs/_includes/header.html @@ -0,0 +1,36 @@ + diff --git a/docs/_layouts/alt-page.html b/docs/_layouts/alt-page.html new file mode 100644 index 00000000000..5dbc6ef245f --- /dev/null +++ b/docs/_layouts/alt-page.html @@ -0,0 +1,14 @@ +--- +layout: default +--- +
+ +
+

{{ page.alt_title | escape }}

+
+ +
+ {{ content }} +
+ +
diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html new file mode 100644 index 00000000000..e092cd572e0 --- /dev/null +++ b/docs/_layouts/default.html @@ -0,0 +1,18 @@ + + + + {%- include head.html -%} + + + + {%- include header.html -%} + +
+
+ {{ content }} +
+
+ + + + diff --git a/docs/_layouts/page.html b/docs/_layouts/page.html new file mode 100644 index 00000000000..01e4b2a93b8 --- /dev/null +++ b/docs/_layouts/page.html @@ -0,0 +1,14 @@ +--- +layout: default +--- +
+ +
+

{{ page.title | escape }}

+
+ +
+ {{ content }} +
+ +
diff --git a/docs/_sass/minima/_base.scss b/docs/_sass/minima/_base.scss new file mode 100644 index 00000000000..0d3f6e80ced --- /dev/null +++ b/docs/_sass/minima/_base.scss @@ -0,0 +1,295 @@ +html { + font-size: $base-font-size; +} + +/** + * Reset some basic elements + */ +body, h1, h2, h3, h4, h5, h6, +p, blockquote, pre, hr, +dl, dd, ol, ul, figure { + margin: 0; + padding: 0; + +} + + + +/** + * Basic styling + */ +body { + font: $base-font-weight #{$base-font-size}/#{$base-line-height} $base-font-family; + color: $text-color; + background-color: $background-color; + -webkit-text-size-adjust: 100%; + -webkit-font-feature-settings: "kern" 1; + -moz-font-feature-settings: "kern" 1; + -o-font-feature-settings: "kern" 1; + font-feature-settings: "kern" 1; + font-kerning: normal; + display: flex; + min-height: 100vh; + flex-direction: column; + overflow-wrap: break-word; +} + + + +/** + * Set `margin-bottom` to maintain vertical rhythm + */ +h1, h2, h3, h4, h5, h6, +p, blockquote, pre, +ul, ol, dl, figure, +%vertical-rhythm { + margin-bottom: $spacing-unit / 2; +} + +hr { + margin-top: $spacing-unit; + margin-bottom: $spacing-unit; +} + +/** + * `main` element + */ +main { + display: block; /* Default value of `display` of `main` element is 'inline' in IE 11. */ +} + + + +/** + * Images + */ +img { + max-width: 100%; + vertical-align: middle; +} + + + +/** + * Figures + */ +figure > img { + display: block; +} + +figcaption { + font-size: $small-font-size; +} + + + +/** + * Lists + */ +ul, ol { + margin-left: $spacing-unit; +} + +li { + > ul, + > ol { + margin-bottom: 0; + } +} + + + +/** + * Headings + */ +h1, h2, h3, h4, h5, h6 { + font-weight: $base-font-weight; +} + + + +/** + * Links + */ +a { + color: $link-base-color; + text-decoration: none; + + &:visited { + color: $link-visited-color; + } + + &:hover { + color: $text-color; + text-decoration: underline; + } + + .social-media-list &:hover { + text-decoration: none; + + .username { + text-decoration: underline; + } + } +} + + +/** + * Blockquotes + */ +blockquote { + color: $brand-color; + border-left: 4px solid $brand-color-light; + padding-left: $spacing-unit / 2; + @include relative-font-size(1.125); + font-style: italic; + + > :last-child { + margin-bottom: 0; + } + + i, em { + font-style: normal; + } +} + + + +/** + * Code formatting + */ +pre, +code { + font-family: $code-font-family; + font-size: 0.9375em; + border: 1px solid $brand-color-light; + border-radius: 3px; + background-color: $code-background-color; +} + +code { + padding: 1px 5px; +} + +pre { + padding: 8px 12px; + overflow-x: auto; + + > code { + border: 0; + padding-right: 0; + padding-left: 0; + } +} + +.highlight { + border-radius: 3px; + background: $code-background-color; + @extend %vertical-rhythm; + + .highlighter-rouge & { + background: $code-background-color; + } +} + + + +/** + * Wrapper + */ +.wrapper { + max-width: calc(#{$content-width} - (#{$spacing-unit})); + margin-right: auto; + margin-left: auto; + padding-right: $spacing-unit / 2; + padding-left: $spacing-unit / 2; + @extend %clearfix; + + @media screen and (min-width: $on-large) { + max-width: calc(#{$content-width} - (#{$spacing-unit} * 2)); + padding-right: $spacing-unit; + padding-left: $spacing-unit; + } +} + + + +/** + * Clearfix + */ +%clearfix:after { + content: ""; + display: table; + clear: both; +} + + + +/** + * Icons + */ + +.orange { + color: #f66a0a; +} + +.grey { + color: #828282; +} + +/** + * Tables + */ +table { + margin-bottom: $spacing-unit; + width: 100%; + text-align: $table-text-align; + color: $table-text-color; + border-collapse: collapse; + border: 1px solid $table-border-color; + tr { + &:nth-child(even) { + background-color: $table-zebra-color; + } + } + th, td { + padding: ($spacing-unit / 3) ($spacing-unit / 2); + } + th { + background-color: $table-header-bg-color; + border: 1px solid $table-header-border; + } + td { + border: 1px solid $table-border-color; + } + + @include media-query($on-laptop) { + display: block; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + } +} + +@media print { + /** + * Prevents page break from cutting through content when printing + */ + body { + display: block; + } + /** + * Replaces the top navigation menu with the project name when printing + */ + .site-header .wrapper { + display: none; + } + .site-header { + text-align: center; + } + .site-header:before { + content: "AB-3"; + font-size: 32px; + } +} + diff --git a/docs/_sass/minima/_layout.scss b/docs/_sass/minima/_layout.scss new file mode 100644 index 00000000000..ca99f981701 --- /dev/null +++ b/docs/_sass/minima/_layout.scss @@ -0,0 +1,263 @@ +/** + * Site header + */ +.site-header { + border-top: 5px solid $brand-color-dark; + border-bottom: 1px solid $brand-color-light; + min-height: $spacing-unit * 1.865; + line-height: $base-line-height * $base-font-size * 2.25; + + // Positioning context for the mobile navigation icon + position: relative; +} + +.site-title { + @include relative-font-size(1.625); + font-weight: 300; + letter-spacing: -1px; + margin-bottom: 0; + float: left; + + @include media-query($on-palm) { + padding-right: 45px; + } + + &, + &:visited { + color: $brand-color-dark; + } +} + +.site-nav { + position: absolute; + top: 9px; + right: $spacing-unit / 2; + background-color: $background-color; + border: 1px solid $brand-color-light; + border-radius: 5px; + text-align: right; + + .nav-trigger { + display: none; + } + + .menu-icon { + float: right; + width: 36px; + height: 26px; + line-height: 0; + padding-top: 10px; + text-align: center; + + > svg path { + fill: $brand-color-dark; + } + } + + label[for="nav-trigger"] { + display: block; + float: right; + width: 36px; + height: 36px; + z-index: 2; + cursor: pointer; + } + + input ~ .trigger { + clear: both; + display: none; + } + + input:checked ~ .trigger { + display: block; + padding-bottom: 5px; + } + + .page-link { + color: $text-color; + line-height: $base-line-height; + display: block; + padding: 5px 10px; + + // Gaps between nav items, but not on the last one + &:not(:last-child) { + margin-right: 0; + } + margin-left: 20px; + } + + @media screen and (min-width: $on-medium) { + position: static; + float: right; + border: none; + background-color: inherit; + + label[for="nav-trigger"] { + display: none; + } + + .menu-icon { + display: none; + } + + input ~ .trigger { + display: block; + } + + .page-link { + display: inline; + padding: 0; + + &:not(:last-child) { + margin-right: 20px; + } + margin-left: auto; + } + } +} + + + +/** + * Page content + */ +.page-content { + padding: $spacing-unit 0; + flex: 1 0 auto; +} + +.page-heading { + @include relative-font-size(2); +} + +.post-list-heading { + @include relative-font-size(1.75); +} + +.post-list { + margin-left: 0; + list-style: none; + + > li { + margin-bottom: $spacing-unit; + } +} + +.post-meta { + font-size: $small-font-size; + color: $brand-color; +} + +.post-link { + display: block; + @include relative-font-size(1.5); +} + + + +/** + * Posts + */ +.post-header { + margin-bottom: $spacing-unit; +} + +.post-title, +.post-content h1 { + @include relative-font-size(2.625); + letter-spacing: -1px; + line-height: 1.15; + + @media screen and (min-width: $on-large) { + @include relative-font-size(2.625); + } +} + +.post-content { + margin-bottom: $spacing-unit; + + h1, h2, h3 { margin-top: $spacing-unit * 2 } + h4, h5, h6 { margin-top: $spacing-unit } + + h2 { + @include relative-font-size(1.75); + + @media screen and (min-width: $on-large) { + @include relative-font-size(2); + } + } + + h3 { + @include relative-font-size(1.375); + + @media screen and (min-width: $on-large) { + @include relative-font-size(1.625); + } + } + + h4 { + @include relative-font-size(1.25); + } + + h5 { + @include relative-font-size(1.125); + } + h6 { + @include relative-font-size(1.0625); + } +} + + +.social-media-list { + display: table; + margin: 0 auto; + li { + float: left; + margin: 5px 10px 5px 0; + &:last-of-type { margin-right: 0 } + a { + display: block; + padding: $spacing-unit / 4; + border: 1px solid $brand-color-light; + &:hover { border-color: darken($brand-color-light, 10%) } + } + } +} + + + +/** + * Pagination navbar + */ +.pagination { + margin-bottom: $spacing-unit; + @extend .social-media-list; + li { + a, div { + min-width: 41px; + text-align: center; + box-sizing: border-box; + } + div { + display: block; + padding: $spacing-unit / 4; + border: 1px solid transparent; + + &.pager-edge { + color: darken($brand-color-light, 5%); + border: 1px dashed; + } + } + } +} + + + +/** + * Grid helpers + */ +@media screen and (min-width: $on-large) { + .one-half { + width: calc(50% - (#{$spacing-unit} / 2)); + } +} diff --git a/docs/_sass/minima/custom-mixins.scss b/docs/_sass/minima/custom-mixins.scss new file mode 100644 index 00000000000..9d4bedc1c67 --- /dev/null +++ b/docs/_sass/minima/custom-mixins.scss @@ -0,0 +1,21 @@ +@mixin alert-variant($background, $border, $color) { + color: $color; + @include gradient-bg($background); + border-color: $border; + + .alert-link { + color: darken($color, 10%); + } +} + +@mixin gradient-bg($color, $foreground: null) { + @if $enable-gradients { + @if $foreground { + background-image: $foreground, linear-gradient(180deg, mix($body-bg, $color, 15%), $color); + } @else { + background-image: linear-gradient(180deg, mix($body-bg, $color, 15%), $color); + } + } @else { + background-color: $color; + } +} diff --git a/docs/_sass/minima/custom-styles.scss b/docs/_sass/minima/custom-styles.scss new file mode 100644 index 00000000000..56b5d56b430 --- /dev/null +++ b/docs/_sass/minima/custom-styles.scss @@ -0,0 +1,34 @@ +// Placeholder to allow defining custom styles that override everything else. +// (Use `_sass/minima/custom-variables.scss` to override variable defaults) +h2, h3, h4, h5, h6 { + color: #e46c0a; +} + +// Bootstrap style alerts +.alert { + position: relative; + padding: $alert-padding-y $alert-padding-x; + margin-bottom: $alert-margin-bottom; + border: $alert-border-width solid transparent; + border-radius : $alert-border-radius; +} + +// Headings for larger alerts +.alert-heading { + // Specified to prevent conflicts of changing $headings-color + color: inherit; +} + +// Provide class for links that match alerts +.alert-link { + font-weight: $alert-link-font-weight; +} + +// Generate contextual modifier classes for colorizing the alert. + +@each $color, $value in $theme-colors { + .alert-#{$color} { + @include alert-variant(color-level($value, $alert-bg-level), color-level($value, $alert-border-level), color-level($value, $alert-color-level)); + } +} + diff --git a/docs/_sass/minima/custom-variables.scss b/docs/_sass/minima/custom-variables.scss new file mode 100644 index 00000000000..a128970cbe7 --- /dev/null +++ b/docs/_sass/minima/custom-variables.scss @@ -0,0 +1,76 @@ +// Placeholder to allow overriding predefined variables smoothly. + +//Bootstrap's default +$white: #fff !default; +$gray-100: #f8f9fa !default; +$gray-200: #e9ecef !default; +$gray-300: #dee2e6 !default; +$gray-400: #ced4da !default; +$gray-500: #adb5bd !default; +$gray-600: #6c757d !default; +$gray-700: #495057 !default; +$gray-800: #343a40 !default; +$gray-900: #212529 !default; +$black: #000 !default; +$blue: #0d6efd !default; +$indigo: #6610f2 !default; +$purple: #6f42c1 !default; +$pink: #d63384 !default; +$red: #dc3545 !default; +$orange: #fd7e14 !default; +$yellow: #ffc107 !default; +$green: #28a745 !default; +$teal: #20c997 !default; +$cyan: #17a2b8 !default; + +$primary: $blue !default; +$secondary: $gray-600 !default; +$success: $green !default; +$info: $cyan !default; +$warning: $yellow !default; +$danger: $red !default; +$light: $gray-100 !default; +$dark: $gray-800 !default; + +$theme-colors: ( + "primary": $primary, + "secondary": $secondary, + "success": $success, + "info": $info, + "warning": $warning, + "danger": $danger, + "light": $light, + "dark": $dark +) !default; + +$theme-color-interval: 8% !default; + +$body-bg: $white !default; +$body-color: $gray-900 !default; +$body-text-align: null !default; + +$enable-gradients: true; + +// Define alert colors, border radius, and padding. +$border-radius: .25rem !default; +$border-width: 1px !default; +$font-weight-bold: 700 !default; + +$alert-padding-y: .75rem !default; +$alert-padding-x: 1.25rem !default; +$alert-margin-bottom: 1rem !default; +$alert-border-radius: $border-radius !default; +$alert-link-font-weight: $font-weight-bold !default; +$alert-border-width: $border-width !default; + +$alert-bg-level: -10 !default; +$alert-border-level: -9 !default; +$alert-color-level: 6 !default; + +// Request a color level +// scss-docs-start color-level +@function color-level($color: $primary, $level: 0) { + $color-base: if($level > 0, $black, $white); + $level: abs($level); + @return mix($color-base, $color, $level * $theme-color-interval); +} diff --git a/docs/_sass/minima/initialize.scss b/docs/_sass/minima/initialize.scss new file mode 100644 index 00000000000..30288811151 --- /dev/null +++ b/docs/_sass/minima/initialize.scss @@ -0,0 +1,51 @@ +@charset "utf-8"; + +// Define defaults for each variable. + +$base-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Segoe UI Symbol", "Segoe UI Emoji", "Apple Color Emoji", Roboto, Helvetica, Arial, sans-serif !default; +$code-font-family: "Menlo", "Inconsolata", "Consolas", "Roboto Mono", "Ubuntu Mono", "Liberation Mono", "Courier New", monospace; +$base-font-size: 16px !default; +$base-font-weight: 400 !default; +$small-font-size: $base-font-size * 0.875 !default; +$base-line-height: 1.5 !default; + +$spacing-unit: 30px !default; + +$table-text-align: left !default; + +// Width of the content area +$content-width: 800px !default; + +$on-palm: 600px !default; +$on-laptop: 800px !default; + +$on-medium: $on-palm !default; +$on-large: $on-laptop !default; + +// Use media queries like this: +// @include media-query($on-palm) { +// .wrapper { +// padding-right: $spacing-unit / 2; +// padding-left: $spacing-unit / 2; +// } +// } +// Notice the following mixin uses max-width, in a deprecated, desktop-first +// approach, whereas media queries used elsewhere now use min-width. +@mixin media-query($device) { + @media screen and (max-width: $device) { + @content; + } +} + +@mixin relative-font-size($ratio) { + font-size: #{$ratio}rem; +} + +// Import pre-styling-overrides hook and style-partials. +@import + "minima/custom-variables", // Hook to override predefined variables. + "minima/custom-mixins", // Hook to add custom mixins. + "minima/base", // Defines element resets. + "minima/layout", // Defines structure and style based on CSS selectors. + "minima/custom-styles" // Hook to override existing styles. +; diff --git a/docs/_sass/minima/skins/classic.scss b/docs/_sass/minima/skins/classic.scss new file mode 100644 index 00000000000..37ea9c5244c --- /dev/null +++ b/docs/_sass/minima/skins/classic.scss @@ -0,0 +1,84 @@ +@charset "utf-8"; + +$brand-color: #828282 !default; +$brand-color-light: lighten($brand-color, 40%) !default; +$brand-color-dark: darken($brand-color, 25%) !default; + +$text-color: #111 !default; +$background-color: #fdfdfd !default; +$code-background-color: #eef !default; + +$link-base-color: #2a7ae2 !default; +$link-visited-color: darken($link-base-color, 15%) !default; + +$table-text-color: lighten($text-color, 18%) !default; +$table-zebra-color: lighten($brand-color, 46%) !default; +$table-header-bg-color: lighten($brand-color, 43%) !default; +$table-header-border: lighten($brand-color, 36%) !default; +$table-border-color: $brand-color-light !default; + + +// Syntax highlighting styles should be adjusted appropriately for every "skin" +// ---------------------------------------------------------------------------- + +.highlight { + .c { color: #998; font-style: italic } // Comment + .err { color: #a61717; background-color: #e3d2d2 } // Error + .k { font-weight: bold } // Keyword + .o { font-weight: bold } // Operator + .cm { color: #998; font-style: italic } // Comment.Multiline + .cp { color: #999; font-weight: bold } // Comment.Preproc + .c1 { color: #998; font-style: italic } // Comment.Single + .cs { color: #999; font-weight: bold; font-style: italic } // Comment.Special + .gd { color: #000; background-color: #fdd } // Generic.Deleted + .gd .x { color: #000; background-color: #faa } // Generic.Deleted.Specific + .ge { font-style: italic } // Generic.Emph + .gr { color: #a00 } // Generic.Error + .gh { color: #999 } // Generic.Heading + .gi { color: #000; background-color: #dfd } // Generic.Inserted + .gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific + .go { color: #888 } // Generic.Output + .gp { color: #555 } // Generic.Prompt + .gs { font-weight: bold } // Generic.Strong + .gu { color: #aaa } // Generic.Subheading + .gt { color: #a00 } // Generic.Traceback + .kc { font-weight: bold } // Keyword.Constant + .kd { font-weight: bold } // Keyword.Declaration + .kp { font-weight: bold } // Keyword.Pseudo + .kr { font-weight: bold } // Keyword.Reserved + .kt { color: #458; font-weight: bold } // Keyword.Type + .m { color: #099 } // Literal.Number + .s { color: #d14 } // Literal.String + .na { color: #008080 } // Name.Attribute + .nb { color: #0086B3 } // Name.Builtin + .nc { color: #458; font-weight: bold } // Name.Class + .no { color: #008080 } // Name.Constant + .ni { color: #800080 } // Name.Entity + .ne { color: #900; font-weight: bold } // Name.Exception + .nf { color: #900; font-weight: bold } // Name.Function + .nn { color: #555 } // Name.Namespace + .nt { color: #000080 } // Name.Tag + .nv { color: #008080 } // Name.Variable + .ow { font-weight: bold } // Operator.Word + .w { color: #bbb } // Text.Whitespace + .mf { color: #099 } // Literal.Number.Float + .mh { color: #099 } // Literal.Number.Hex + .mi { color: #099 } // Literal.Number.Integer + .mo { color: #099 } // Literal.Number.Oct + .sb { color: #d14 } // Literal.String.Backtick + .sc { color: #d14 } // Literal.String.Char + .sd { color: #d14 } // Literal.String.Doc + .s2 { color: #d14 } // Literal.String.Double + .se { color: #d14 } // Literal.String.Escape + .sh { color: #d14 } // Literal.String.Heredoc + .si { color: #d14 } // Literal.String.Interpol + .sx { color: #d14 } // Literal.String.Other + .sr { color: #009926 } // Literal.String.Regex + .s1 { color: #d14 } // Literal.String.Single + .ss { color: #990073 } // Literal.String.Symbol + .bp { color: #999 } // Name.Builtin.Pseudo + .vc { color: #008080 } // Name.Variable.Class + .vg { color: #008080 } // Name.Variable.Global + .vi { color: #008080 } // Name.Variable.Instance + .il { color: #099 } // Literal.Number.Integer.Long +} diff --git a/docs/_sass/minima/skins/solarized-dark.scss b/docs/_sass/minima/skins/solarized-dark.scss new file mode 100644 index 00000000000..f3b1f387de0 --- /dev/null +++ b/docs/_sass/minima/skins/solarized-dark.scss @@ -0,0 +1,4 @@ +@charset "utf-8"; + +$sol-is-dark: true; +@import "minima/skins/solarized"; diff --git a/docs/_sass/minima/skins/solarized.scss b/docs/_sass/minima/skins/solarized.scss new file mode 100644 index 00000000000..982bd7f2990 --- /dev/null +++ b/docs/_sass/minima/skins/solarized.scss @@ -0,0 +1,133 @@ +@charset "utf-8"; + +// Solarized skin +// ============== +// Created by Sander Voerman using the Solarized +// color scheme by Ethan Schoonover . + +// This style sheet implements two options for the minima.skin setting: +// "solarized" for light mode and "solarized-dark" for dark mode. +$sol-is-dark: false !default; + + +// Color scheme +// ------------ +// The inline comments show the canonical L*a*b values for each color. + +$sol-base03: #002b36; // 15 -12 -12 +$sol-base02: #073642; // 20 -12 -12 +$sol-base01: #586e75; // 45 -07 -07 +$sol-base00: #657b83; // 50 -07 -07 +$sol-base0: #839496; // 60 -06 -03 +$sol-base1: #93a1a1; // 65 -05 -02 +$sol-base2: #eee8d5; // 92 -00 10 +$sol-base3: #fdf6e3; // 97 00 10 +$sol-yellow: #b58900; // 60 10 65 +$sol-orange: #cb4b16; // 50 50 55 +$sol-red: #dc322f; // 50 65 45 +$sol-magenta: #d33682; // 50 65 -05 +$sol-violet: #6c71c4; // 50 15 -45 +$sol-blue: #268bd2; // 55 -10 -45 +$sol-cyan: #2aa198; // 60 -35 -05 +$sol-green: #859900; // 60 -20 65 + +$sol-mono3: $sol-base3; +$sol-mono2: $sol-base2; +$sol-mono1: $sol-base1; +$sol-mono00: $sol-base00; +$sol-mono01: $sol-base01; + +@if $sol-is-dark { + $sol-mono3: $sol-base03; + $sol-mono2: $sol-base02; + $sol-mono1: $sol-base01; + $sol-mono00: $sol-base0; + $sol-mono01: $sol-base1; +} + + +// Minima color variables +// ---------------------- + +$brand-color: $sol-mono1 !default; +$brand-color-light: mix($sol-mono1, $sol-mono3) !default; +$brand-color-dark: $sol-mono00 !default; + +$text-color: $sol-mono01 !default; +$background-color: $sol-mono3 !default; +$code-background-color: $sol-mono2 !default; + +$link-base-color: $sol-blue !default; +$link-visited-color: mix($sol-blue, $sol-mono00) !default; + +$table-text-color: $sol-mono00 !default; +$table-zebra-color: mix($sol-mono2, $sol-mono3) !default; +$table-header-bg-color: $sol-mono2 !default; +$table-header-border: $sol-mono1 !default; +$table-border-color: $sol-mono1 !default; + + +// Syntax highlighting styles +// -------------------------- + +.highlight { + .c { color: $sol-mono1; font-style: italic } // Comment + .err { color: $sol-red } // Error + .k { color: $sol-mono01; font-weight: bold } // Keyword + .o { color: $sol-mono01; font-weight: bold } // Operator + .cm { color: $sol-mono1; font-style: italic } // Comment.Multiline + .cp { color: $sol-mono1; font-weight: bold } // Comment.Preproc + .c1 { color: $sol-mono1; font-style: italic } // Comment.Single + .cs { color: $sol-mono1; font-weight: bold; font-style: italic } // Comment.Special + .gd { color: $sol-red } // Generic.Deleted + .gd .x { color: $sol-red } // Generic.Deleted.Specific + .ge { color: $sol-mono00; font-style: italic } // Generic.Emph + .gr { color: $sol-red } // Generic.Error + .gh { color: $sol-mono1 } // Generic.Heading + .gi { color: $sol-green } // Generic.Inserted + .gi .x { color: $sol-green } // Generic.Inserted.Specific + .go { color: $sol-mono00 } // Generic.Output + .gp { color: $sol-mono00 } // Generic.Prompt + .gs { color: $sol-mono01; font-weight: bold } // Generic.Strong + .gu { color: $sol-mono1 } // Generic.Subheading + .gt { color: $sol-red } // Generic.Traceback + .kc { color: $sol-mono01; font-weight: bold } // Keyword.Constant + .kd { color: $sol-mono01; font-weight: bold } // Keyword.Declaration + .kp { color: $sol-mono01; font-weight: bold } // Keyword.Pseudo + .kr { color: $sol-mono01; font-weight: bold } // Keyword.Reserved + .kt { color: $sol-violet; font-weight: bold } // Keyword.Type + .m { color: $sol-cyan } // Literal.Number + .s { color: $sol-magenta } // Literal.String + .na { color: $sol-cyan } // Name.Attribute + .nb { color: $sol-blue } // Name.Builtin + .nc { color: $sol-violet; font-weight: bold } // Name.Class + .no { color: $sol-cyan } // Name.Constant + .ni { color: $sol-violet } // Name.Entity + .ne { color: $sol-violet; font-weight: bold } // Name.Exception + .nf { color: $sol-blue; font-weight: bold } // Name.Function + .nn { color: $sol-mono00 } // Name.Namespace + .nt { color: $sol-blue } // Name.Tag + .nv { color: $sol-cyan } // Name.Variable + .ow { color: $sol-mono01; font-weight: bold } // Operator.Word + .w { color: $sol-mono1 } // Text.Whitespace + .mf { color: $sol-cyan } // Literal.Number.Float + .mh { color: $sol-cyan } // Literal.Number.Hex + .mi { color: $sol-cyan } // Literal.Number.Integer + .mo { color: $sol-cyan } // Literal.Number.Oct + .sb { color: $sol-magenta } // Literal.String.Backtick + .sc { color: $sol-magenta } // Literal.String.Char + .sd { color: $sol-magenta } // Literal.String.Doc + .s2 { color: $sol-magenta } // Literal.String.Double + .se { color: $sol-magenta } // Literal.String.Escape + .sh { color: $sol-magenta } // Literal.String.Heredoc + .si { color: $sol-magenta } // Literal.String.Interpol + .sx { color: $sol-magenta } // Literal.String.Other + .sr { color: $sol-green } // Literal.String.Regex + .s1 { color: $sol-magenta } // Literal.String.Single + .ss { color: $sol-magenta } // Literal.String.Symbol + .bp { color: $sol-mono1 } // Name.Builtin.Pseudo + .vc { color: $sol-cyan } // Name.Variable.Class + .vg { color: $sol-cyan } // Name.Variable.Global + .vi { color: $sol-cyan } // Name.Variable.Instance + .il { color: $sol-cyan } // Literal.Number.Integer.Long +} diff --git a/docs/assets/css/style.scss b/docs/assets/css/style.scss new file mode 100644 index 00000000000..b5ec6976efa --- /dev/null +++ b/docs/assets/css/style.scss @@ -0,0 +1,12 @@ +--- +# Only the main Sass file needs front matter (the dashes are enough) +--- + +@import + "minima/skins/{{ site.minima.skin | default: 'classic' }}", + "minima/initialize"; + +.icon { + height: 21px; + width: 21px +} diff --git a/docs/images/ArchitectureDiagram.png b/docs/images/ArchitectureDiagram.png new file mode 100644 index 00000000000..cd540665053 Binary files /dev/null and b/docs/images/ArchitectureDiagram.png differ diff --git a/docs/images/ArchitectureSequenceDiagram.png b/docs/images/ArchitectureSequenceDiagram.png new file mode 100644 index 00000000000..37ad06a2803 Binary files /dev/null and b/docs/images/ArchitectureSequenceDiagram.png differ diff --git a/docs/images/BetterModelClassDiagram.png b/docs/images/BetterModelClassDiagram.png new file mode 100644 index 00000000000..02a42e35e76 Binary files /dev/null and b/docs/images/BetterModelClassDiagram.png differ diff --git a/docs/images/CommitActivityDiagram.png b/docs/images/CommitActivityDiagram.png new file mode 100644 index 00000000000..5b464126b35 Binary files /dev/null and b/docs/images/CommitActivityDiagram.png differ diff --git a/docs/images/ComponentManagers.png b/docs/images/ComponentManagers.png new file mode 100644 index 00000000000..ae52a35718a Binary files /dev/null and b/docs/images/ComponentManagers.png differ diff --git a/docs/images/DeleteSequenceDiagram.png b/docs/images/DeleteSequenceDiagram.png new file mode 100644 index 00000000000..e186f7ba096 Binary files /dev/null and b/docs/images/DeleteSequenceDiagram.png differ diff --git a/docs/images/LogicClassDiagram.png b/docs/images/LogicClassDiagram.png new file mode 100644 index 00000000000..e3b784310fe Binary files /dev/null and b/docs/images/LogicClassDiagram.png differ diff --git a/docs/images/LogicStorageDIP.png b/docs/images/LogicStorageDIP.png new file mode 100644 index 00000000000..871157f5a9c Binary files /dev/null and b/docs/images/LogicStorageDIP.png differ diff --git a/docs/images/ModelClassDiagram.png b/docs/images/ModelClassDiagram.png new file mode 100644 index 00000000000..a19fb1b4ac8 Binary files /dev/null and b/docs/images/ModelClassDiagram.png differ diff --git a/docs/images/ParserClasses.png b/docs/images/ParserClasses.png new file mode 100644 index 00000000000..edfd1ff7897 Binary files /dev/null and b/docs/images/ParserClasses.png differ diff --git a/docs/images/StorageClassDiagram.png b/docs/images/StorageClassDiagram.png new file mode 100644 index 00000000000..18fa4d0d51f Binary files /dev/null and b/docs/images/StorageClassDiagram.png differ diff --git a/docs/images/UiClassDiagram.png b/docs/images/UiClassDiagram.png new file mode 100644 index 00000000000..11f06d68671 Binary files /dev/null and b/docs/images/UiClassDiagram.png differ diff --git a/docs/images/UndoRedoState0.png b/docs/images/UndoRedoState0.png new file mode 100644 index 00000000000..c5f91b58533 Binary files /dev/null and b/docs/images/UndoRedoState0.png differ diff --git a/docs/images/UndoRedoState1.png b/docs/images/UndoRedoState1.png new file mode 100644 index 00000000000..2d3ad09c047 Binary files /dev/null and b/docs/images/UndoRedoState1.png differ diff --git a/docs/images/UndoRedoState2.png b/docs/images/UndoRedoState2.png new file mode 100644 index 00000000000..20853694e03 Binary files /dev/null and b/docs/images/UndoRedoState2.png differ diff --git a/docs/images/UndoRedoState3.png b/docs/images/UndoRedoState3.png new file mode 100644 index 00000000000..1a9551b31be Binary files /dev/null and b/docs/images/UndoRedoState3.png differ diff --git a/docs/images/UndoRedoState4.png b/docs/images/UndoRedoState4.png new file mode 100644 index 00000000000..46dfae78c94 Binary files /dev/null and b/docs/images/UndoRedoState4.png differ diff --git a/docs/images/UndoRedoState5.png b/docs/images/UndoRedoState5.png new file mode 100644 index 00000000000..f45889b5fdf Binary files /dev/null and b/docs/images/UndoRedoState5.png differ diff --git a/docs/images/UndoSequenceDiagram.png b/docs/images/UndoSequenceDiagram.png new file mode 100644 index 00000000000..c7a7e637266 Binary files /dev/null and b/docs/images/UndoSequenceDiagram.png differ diff --git a/docs/images/tracing/LogicSequenceDiagram.png b/docs/images/tracing/LogicSequenceDiagram.png new file mode 100644 index 00000000000..25c8b66b9f1 Binary files /dev/null and b/docs/images/tracing/LogicSequenceDiagram.png differ diff --git a/docs/index.md b/docs/index.md index 8acbdd73507..7601dbaad0d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,10 +1,8 @@ --- - layout: default.md - title: "" +layout: page +title: AddressBook Level-3 --- -# AddressBook Level-3 - [![CI Status](https://github.com/se-edu/addressbook-level3/workflows/Java%20CI/badge.svg)](https://github.com/se-edu/addressbook-level3/actions) [![codecov](https://codecov.io/gh/se-edu/addressbook-level3/branch/master/graph/badge.svg)](https://codecov.io/gh/se-edu/addressbook-level3) diff --git a/docs/team/johndoe.md b/docs/team/johndoe.md index 86aa7ebfc34..773a07794e2 100644 --- a/docs/team/johndoe.md +++ b/docs/team/johndoe.md @@ -1,6 +1,6 @@ --- - layout: default.md - title: "John Doe's Project Portfolio Page" +layout: page +title: John Doe's Project Portfolio Page --- ### Project: AddressBook Level 3 diff --git a/docs/tutorials/AddRemark.md b/docs/tutorials/AddRemark.md index 8b18f27946b..d98f38982e7 100644 --- a/docs/tutorials/AddRemark.md +++ b/docs/tutorials/AddRemark.md @@ -1,11 +1,8 @@ --- - layout: default.md - title: "Tutorial: Adding a command" - pageNav: 3 +layout: page +title: "Tutorial: Adding a command" --- -# Tutorial: Adding a command - Let's walk you through the implementation of a new command — `remark`. This command allows users of the AddressBook application to add optional remarks to people in their address book and edit it if required. The command should have the following format: @@ -25,7 +22,7 @@ For now, let’s keep `RemarkCommand` as simple as possible and print some outpu **`RemarkCommand.java`:** -```java +``` java package seedu.address.logic.commands; import seedu.address.model.Model; @@ -60,13 +57,13 @@ Run `Main#main` and try out your new `RemarkCommand`. If everything went well, y While we have successfully printed a message to `ResultDisplay`, the command does not do what it is supposed to do. Let’s change the command to throw a `CommandException` to accurately reflect that our command is still a work in progress. - +![The relationship between RemarkCommand and Command](../images/add-remark/RemarkCommandClass.png) Following the convention in other commands, we add relevant messages as constants and use them. **`RemarkCommand.java`:** -```java +``` java public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the remark of the person identified " + "by the index number used in the last person listing. " @@ -93,7 +90,7 @@ Let’s change `RemarkCommand` to parse input from the user. We start by modifying the constructor of `RemarkCommand` to accept an `Index` and a `String`. While we are at it, let’s change the error message to echo the values. While this is not a replacement for tests, it is an obvious way to tell if our code is functioning as intended. -```java +``` java import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; //... public class RemarkCommand extends Command { @@ -145,13 +142,13 @@ Now let’s move on to writing a parser that will extract the index and remark f Create a `RemarkCommandParser` class in the `seedu.address.logic.parser` package. The class must extend the `Parser` interface. - +![The relationship between Parser and RemarkCommandParser](../images/add-remark/RemarkCommandParserClass.png) Thankfully, `ArgumentTokenizer#tokenize()` makes it trivial to parse user input. Let’s take a look at the JavaDoc provided for the function to understand what it does. **`ArgumentTokenizer.java`:** -```java +``` java /** * Tokenizes an arguments string and returns an {@code ArgumentMultimap} * object that maps prefixes to their respective argument values. Only the @@ -169,7 +166,7 @@ We can tell `ArgumentTokenizer#tokenize()` to look out for our new prefix `r/` a **`ArgumentMultimap.java`:** -```java +``` java /** * Returns the last value of {@code prefix}. */ @@ -184,7 +181,7 @@ This appears to be what we need to get a String of the remark. But what about th **`DeleteCommandParser.java`:** -```java +``` java Index index = ParserUtil.parseIndex(args); return new DeleteCommand(index); ``` @@ -195,7 +192,7 @@ Now that we have the know-how to extract the data that we need from the user’s **`RemarkCommandParser.java`:** -```java +``` java public RemarkCommand parse(String args) throws ParseException { requireNonNull(args); ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, @@ -215,11 +212,11 @@ public RemarkCommand parse(String args) throws ParseException { } ``` - +
-Don’t forget to update `AddressBookParser` to use our new `RemarkCommandParser`! +:information_source: Don’t forget to update `AddressBookParser` to use our new `RemarkCommandParser`! - +
If you are stuck, check out the sample [here](https://github.com/se-edu/addressbook-level3/commit/dc6d5139d08f6403da0ec624ea32bd79a2ae0cbf#diff-8bf239e8e9529369b577701303ddd96af93178b4ed6735f91c2d8488b20c6b4a). @@ -247,7 +244,7 @@ Simply add the following to [`seedu.address.ui.PersonCard`](https://github.com/s **`PersonCard.java`:** -```java +``` java @FXML private Label remark; ``` @@ -279,11 +276,11 @@ We change the constructor of `Person` to take a `Remark`. We will also need to d Unfortunately, a change to `Person` will cause other commands to break, you will have to modify these commands to use the updated `Person`! - +
-Use the `Find Usages` feature in IntelliJ IDEA on the `Person` class to find these commands. +:bulb: Use the `Find Usages` feature in IntelliJ IDEA on the `Person` class to find these commands. - +
Refer to [this commit](https://github.com/se-edu/addressbook-level3/commit/ce998c37e65b92d35c91d28c7822cd139c2c0a5c) and check that you have got everything in order! @@ -294,11 +291,11 @@ AddressBook stores data by serializing `JsonAdaptedPerson` into `json` with the While the changes to code may be minimal, the test data will have to be updated as well. - +
-You must delete AddressBook’s storage file located at `/data/addressbook.json` before running it! Not doing so will cause AddressBook to default to an empty address book! +:exclamation: You must delete AddressBook’s storage file located at `/data/addressbook.json` before running it! Not doing so will cause AddressBook to default to an empty address book! - +
Check out [this commit](https://github.com/se-edu/addressbook-level3/commit/556cbd0e03ff224d7a68afba171ad2eb0ce56bbf) to see what the changes entail. @@ -311,7 +308,7 @@ Just add [this one line of code!](https://github.com/se-edu/addressbook-level3/c **`PersonCard.java`:** -```java +``` java public PersonCard(Person person, int displayedIndex) { //... remark.setText(person.getRemark().value); @@ -331,7 +328,7 @@ save it with `Model#setPerson()`. **`RemarkCommand.java`:** -```java +``` java //... public static final String MESSAGE_ADD_REMARK_SUCCESS = "Added remark to Person: %1$s"; public static final String MESSAGE_DELETE_REMARK_SUCCESS = "Removed remark from Person: %1$s"; diff --git a/docs/tutorials/RemovingFields.md b/docs/tutorials/RemovingFields.md index c73bd379e5e..f29169bc924 100644 --- a/docs/tutorials/RemovingFields.md +++ b/docs/tutorials/RemovingFields.md @@ -1,11 +1,8 @@ --- - layout: default.md - title: "Tutorial: Removing Fields" - pageNav: 3 +layout: page +title: "Tutorial: Removing Fields" --- -# Tutorial: Removing Fields - > Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. > > — Antoine de Saint-Exupery @@ -13,17 +10,17 @@ When working on an existing code base, you will most likely find that some features that are no longer necessary. This tutorial aims to give you some practice on such a code 'removal' activity by removing the `address` field from `Person` class. - +
**If you have done the [Add `remark` command tutorial](AddRemark.html) already**, you should know where the code had to be updated to add the field `remark`. From that experience, you can deduce where the code needs to be changed to _remove_ that field too. The removing of the `address` field can be done similarly.

However, if you have no such prior knowledge, removing a field can take a quite a bit of detective work. This tutorial takes you through that process. **At least have a read even if you don't actually do the steps yourself.** - +
- - +* Table of Contents +{:toc} ## Safely deleting `Address` @@ -53,10 +50,10 @@ Let’s try removing references to `Address` in `EditPersonDescriptor`. 1. Remove the usages of `address` and select `Do refactor` when you are done. - +
- **Tip:** Removing usages may result in errors. Exercise discretion and fix them. For example, removing the `address` field from the `Person` class will require you to modify its constructor. - + :bulb: **Tip:** Removing usages may result in errors. Exercise discretion and fix them. For example, removing the `address` field from the `Person` class will require you to modify its constructor. +
1. Repeat the steps for the remaining usages of `Address` @@ -74,7 +71,7 @@ A quick look at the `PersonCard` class and its `fxml` file quickly reveals why i **`PersonCard.java`** -```java +``` java ... @FXML private Label address; diff --git a/docs/tutorials/TracingCode.md b/docs/tutorials/TracingCode.md index 2b1b0f2d6b7..4fb62a83ef6 100644 --- a/docs/tutorials/TracingCode.md +++ b/docs/tutorials/TracingCode.md @@ -1,30 +1,26 @@ --- - layout: default.md - title: "Tutorial: Tracing code" - pageNav: 3 +layout: page +title: "Tutorial: Tracing code" --- -# Tutorial: Tracing code - - > Indeed, the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code. …​\[Therefore,\] making it easy to read makes it easier to write. > > — Robert C. Martin Clean Code: A Handbook of Agile Software Craftsmanship When trying to understand an unfamiliar code base, one common strategy used is to trace some representative execution path through the code base. One easy way to trace an execution path is to use a debugger to step through the code. In this tutorial, you will be using the IntelliJ IDEA’s debugger to trace the execution path of a specific user command. - - +* Table of Contents +{:toc} ## Before we start Before we jump into the code, it is useful to get an idea of the overall structure and the high-level behavior of the application. This is provided in the 'Architecture' section of the developer guide. In particular, the architecture diagram (reproduced below), tells us that the App consists of several components. - +![ArchitectureDiagram](../images/ArchitectureDiagram.png) It also has a sequence diagram (reproduced below) that tells us how a command propagates through the App. - + Note how the diagram shows only the execution flows _between_ the main components. That is, it does not show details of the execution path *inside* each component. By hiding those details, the diagram aims to inform the reader about the overall execution path of a command without overwhelming the reader with too much details. In this tutorial, you aim to find those omitted details so that you get a more in-depth understanding of how the code works. @@ -41,16 +37,16 @@ As you know, the first step of debugging is to put in a breakpoint where you wan In our case, we would want to begin the tracing at the very point where the App start processing user input (i.e., somewhere in the UI component), and then trace through how the execution proceeds through the UI component. However, the execution path through a GUI is often somewhat obscure due to various *event-driven mechanisms* used by GUI frameworks, which happens to be the case here too. Therefore, let us put the breakpoint where the `UI` transfers control to the `Logic` component. - + According to the sequence diagram you saw earlier (and repeated above for reference), the `UI` component yields control to the `Logic` component through a method named `execute`. Searching through the code base for an `execute()` method that belongs to the `Logic` component yields a promising candidate in `seedu.address.logic.Logic`. - +
-**Intellij Tip:** The ['**Search Everywhere**' feature](https://www.jetbrains.com/help/idea/searching-everywhere.html) can be used here. In particular, the '**Find Symbol**' ('Symbol' here refers to methods, variables, classes etc.) variant of that feature is quite useful here as we are looking for a _method_ named `execute`, not simply the text `execute`. - +:bulb: **Intellij Tip:** The ['**Search Everywhere**' feature](https://www.jetbrains.com/help/idea/searching-everywhere.html) can be used here. In particular, the '**Find Symbol**' ('Symbol' here refers to methods, variables, classes etc.) variant of that feature is quite useful here as we are looking for a _method_ named `execute`, not simply the text `execute`. +
A quick look at the `seedu.address.logic.Logic` (an extract given below) confirms that this indeed might be what we’re looking for. @@ -71,14 +67,14 @@ public interface Logic { But apparently, this is an interface, not a concrete implementation. That should be fine because the [Architecture section of the Developer Guide](../DeveloperGuide.html#architecture) tells us that components interact through interfaces. Here's the relevant diagram: - + Next, let's find out which statement(s) in the `UI` code is calling this method, thus transferring control from the `UI` to the `Logic`. - +
-**Intellij Tip:** The ['**Find Usages**' feature](https://www.jetbrains.com/help/idea/find-highlight-usages.html#find-usages) can find from which parts of the code a class/method/variable is being used. - +:bulb: **Intellij Tip:** The ['**Find Usages**' feature](https://www.jetbrains.com/help/idea/find-highlight-usages.html#find-usages) can find from which parts of the code a class/method/variable is being used. +
![`Find Usages` tool window. `Edit` \> `Find` \> `Find Usages`.](../images/tracing/FindUsages.png) @@ -91,10 +87,10 @@ Now let’s set the breakpoint. First, double-click the item to reach the corres Recall from the User Guide that the `edit` command has the format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]…​` For this tutorial we will be issuing the command `edit 1 n/Alice Yeoh`. - +
-**Tip:** Over the course of the debugging session, you will encounter every major component in the application. Try to keep track of what happens inside the component and where the execution transfers to another component. - +:bulb: **Tip:** Over the course of the debugging session, you will encounter every major component in the application. Try to keep track of what happens inside the component and where the execution transfers to another component. +
1. To start the debugging session, simply `Run` \> `Debug Main` @@ -114,7 +110,7 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [ **LogicManager\#execute().** - ```java + ``` java @Override public CommandResult execute(String commandText) throws CommandException, ParseException { @@ -146,7 +142,7 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [ ![StepOver](../images/tracing/StepOver.png) 1. _Step into_ the line where user input in parsed from a String to a Command, which should bring you to the `AddressBookParser#parseCommand()` method (partial code given below): - ```java + ``` java public Command parseCommand(String userInput) throws ParseException { ... final String commandWord = matcher.group("commandWord"); @@ -161,7 +157,7 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [ 1. Stepping through the `switch` block, we end up at a call to `EditCommandParser().parse()` as expected (because the command we typed is an edit command). - ```java + ``` java ... case EditCommand.COMMAND_WORD: return new EditCommandParser().parse(arguments); @@ -170,10 +166,8 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [ 1. Let’s see what `EditCommandParser#parse()` does by stepping into it. You might have to click the 'step into' button multiple times here because there are two method calls in that statement: `EditCommandParser()` and `parse()`. - - - **Intellij Tip:** Sometimes, you might end up stepping into functions that are not of interest. Simply use the `step out` button to get out of them! - +
:bulb: **Intellij Tip:** Sometimes, you might end up stepping into functions that are not of interest. Simply use the `step out` button to get out of them! +
1. Stepping through the method shows that it calls `ArgumentTokenizer#tokenize()` and `ParserUtil#parseIndex()` to obtain the arguments and index required. @@ -181,17 +175,17 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [ ![EditCommand](../images/tracing/EditCommand.png) 1. As you just traced through some code involved in parsing a command, you can take a look at this class diagram to see where the various parsing-related classes you encountered fit into the design of the `Logic` component. - + 1. Let’s continue stepping through until we return to `LogicManager#execute()`. The sequence diagram below shows the details of the execution path through the Logic component. Does the execution path you traced in the code so far match the diagram?
- + ![Tracing an `edit` command through the Logic component](../images/tracing/LogicSequenceDiagram.png) 1. Now, step over until you read the statement that calls the `execute()` method of the `EditCommand` object received, and step into that `execute()` method (partial code given below): **`EditCommand#execute()`:** - ```java + ``` java @Override public CommandResult execute(Model model) throws CommandException { ... @@ -211,28 +205,25 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [ * it uses the `updateFilteredPersonList` method to ask the `Model` to populate the 'filtered list' with _all_ persons.
FYI, The 'filtered list' is the list of persons resulting from the most recent operation that will be shown to the user immediately after. For the `edit` command, we populate it with all the persons so that the user can see the edited person along with all other persons. If this was a `find` command, we would be setting that list to contain the search results instead.
To provide some context, given below is the class diagram of the `Model` component. See if you can figure out where the 'filtered list' of persons is being tracked. -
+
* :bulb: This may be a good time to read through the [`Model` component section of the DG](../DeveloperGuide.html#model-component) 1. As you step through the rest of the statements in the `EditCommand#execute()` method, you'll see that it creates a `CommandResult` object (containing information about the result of the execution) and returns it.
Advancing the debugger by one more step should take you back to the middle of the `LogicManager#execute()` method.
1. Given that you have already seen quite a few classes in the `Logic` component in action, see if you can identify in this partial class diagram some of the classes you've encountered so far, and see how they fit into the class structure of the `Logic` component: - - + * :bulb: This may be a good time to read through the [`Logic` component section of the DG](../DeveloperGuide.html#logic-component) 1. Similar to before, you can step over/into statements in the `LogicManager#execute()` method to examine how the control is transferred to the `Storage` component and what happens inside that component. - - - **Intellij Tip:** When trying to step into a statement such as `storage.saveAddressBook(model.getAddressBook())` which contains multiple method calls, Intellij will let you choose (by clicking) which one you want to step into. - +
:bulb: **Intellij Tip:** When trying to step into a statement such as `storage.saveAddressBook(model.getAddressBook())` which contains multiple method calls, Intellij will let you choose (by clicking) which one you want to step into. +
-1. As you step through the code inside the `Storage` component, you will eventually arrive at the `JsonAddressBook#saveAddressBook()` method which calls the `JsonSerializableAddressBook` constructor, to create an object that can be _serialized_ (i.e., stored in storage medium) in JSON format. That constructor is given below (with added line breaks for easier readability): +1. As you step through the code inside the `Storage` component, you will eventually arrive at the `JsonAddressBook#saveAddressBook()` method which calls the `JsonSerializableAddressBook` constructor, to create an object that can be _serialized_ (i.e., stored in storage medium) in JSON format. That constructor is given below (with added line breaks for easier readability): **`JsonSerializableAddressBook` constructor:** - ```java + ``` java /** * Converts a given {@code ReadOnlyAddressBook} into this class for Jackson use. * @@ -252,8 +243,7 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [ This is because regular Java objects need to go through an _adaptation_ for them to be suitable to be saved in JSON format. 1. While you are stepping through the classes in the `Storage` component, here is the component's class diagram to help you understand how those classes fit into the structure of the component.
- - + * :bulb: This may be a good time to read through the [`Storage` component section of the DG](../DeveloperGuide.html#storage-component) 1. We can continue to step through until you reach the end of the `LogicManager#execute()` method and return to the `MainWindow#executeCommand()` method (the place where we put the original breakpoint). @@ -261,7 +251,7 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [ 1. Stepping into `resultDisplay.setFeedbackToUser(commandResult.getFeedbackToUser());`, we end up in: **`ResultDisplay#setFeedbackToUser()`** - ```java + ``` java public void setFeedbackToUser(String feedbackToUser) { requireNonNull(feedbackToUser); resultDisplay.setText(feedbackToUser);