Skip to content

Commit

Permalink
Merge pull request #2 from ChristopherKlix/v2.0
Browse files Browse the repository at this point in the history
V2.0
  • Loading branch information
ChristopherKlix committed Jan 23, 2021
2 parents becf304 + 764b7cd commit 7fb7bb0
Show file tree
Hide file tree
Showing 28 changed files with 3,639 additions and 850 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ yarn-debug.log*
yarn-error.log*
firebase-debug.log*

# Python
__pycache__/

# Firebase cache
.firebase/

Expand Down
303 changes: 99 additions & 204 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ by Christopher Klix

Thanks a lot for amazing lectures to David J. Malan, Brian Yu, Colton Ogden & the entire CS50 staff!

__*NEW* Updated to v2.0__
<span style="background-color: #E6FFED; color: #22863A">`New Features`</span>
* ASCII 128-255 added (incl. ©, æ, █)
* ASCII codes for 'octal' & 'binary' added
* Improved logic (JS)
* Improved UI & UX (hopefully)
* Bug fixes
* Added Easter Eggs

![GitHub release (latest by date)](https://img.shields.io/github/v/release/ChristopherKlix/ascii50?style=for-the-badge)

![GitHub issues](https://img.shields.io/github/issues/ChristopherKlix/ascii50?style=for-the-badge)
Expand All @@ -16,238 +25,124 @@ Currently live on https://ascii50.firebaseapp.com or https://ascii50.web.app

Both are hosted and secured by [Google Firebase](https://firebase.google.com).

**Please send feature requests or bug reports via the [Google Form](https://forms.gle/2xBZcCashPk7kkgf9)!**
**Please send feature requests or bug reports!**

## Table of contents
1. [Features](#features)
1. [Code explained](#code-explained)
1. [HTML](#html)
1. [SCSS](#scss)
1. [Javascript](#javascript)
1. [Regular Expressions](#regular-expressions)
1. [How to use](#how-to-use)
1. [Commands](#commands)
1. [Code explained](#code-explained)

## Features
## How to use
ASCII50 really is mainly a reference to look up ASCII codes.

**Copy to clipboard**
### Copy to clipboard

You can click on any char and it will copy either the integer or char to your clipboard
You can click on any ASCII code or character (e.g. `64` or `@`) and it will copy it to your clipboard.
Some characters were created (back in the days) for the purpose of controlling devices.
Which is why they are called 'control characters' and are not printable and therefore not 'copy-able'.

**Commands**

You can run commands via the command line. You can find some available commands further down but there are also some shortcuts, easter eggs & secret commands.
Those include ASCII 0-31 & 127.

The command line currently only supports the `ascii50` programm which takes one argument.
### Commands

More detail: [Commands](#commands)
You can run commands via the command line. You can find some available commands further down but there are also some shortcuts, easter eggs & secret commands.

**Upcoming features**
- [x] copy int or char to clipboard
- [ ] add defer to JS script file (next release)
- [ ] improve mobile user interface (next release)
- [ ] explanations for ASCII codes 0-32 & 128 (control characters)
- [ ] type instant conversion (text field to type in 'A' -> duck says '65')
- [ ] maybe interactive duck? - are there APIs for GPT or chatbots?
- [ ] syntax references - converting int to ASCII char in Python, JS etc.
More details: [Commands](#commands)


## Code explained
**Don't be intimidated!** The main content is only in **4 files**:
* index.html
* main.css
* main.js
* ddb.png (the duck)

We use **SCSS** as a pre-processor for CSS. It allows for easier CSS typing and compiles to vanilla CSS before deploying.
* main.scss (compiles to main.css)
* main.css.map (by-product of compilation)

What about the rest?
ASCII50 uses **Google's Firebase** platform for hosting.
It adds a couple of files that allows for using other Firebase services like Auth & Cloud Functions (which we currently don't actually use).
* .firebaserc
* firebase.json

And then there is **Github's** files:
* .gitignore
* README.md (which you are currently reading)

## HTML
The **index.html** file in itself is pretty simple.

By convention, the entire content is wrapped into a `<div id="wrapper">`. It technically is a bit redundant, as `<body>` already does that, but it allows for some more control in CSS for example.

Inside the `<div id="wrapper">` are **three sections**.
* `<div id="header">`
* `<table id="table">`
* `<div id="copyright">`

### header (not `<head>`)
This section contains everything **above** the table. From the title, to the command-line and the duck.

Each sub-section is wrapped into a container `<div>` with a distinct id.
This way, both, CSS and JS can easily reference each individual element.

### table
The table contains... well, nothing really.

The app is currently only available on the web but I'm currently working on making it available as a macOS app as well.
Android & iOS/iPadOS might come as well (probably first as Electron-Wrapper and maybe native at some point).
As this is currently just a fun-project the progress of this undertaking depends on motivation and time :).

### Repo structure
The root directory contains **no** app-relevant code.

___

#### /root/
```sh
/root/
├─ app/
│ └─ ...
├─ web/
│ └─ ...
├─ .gitignoe
├─ LICENSE
├─ README.md (this file)
├─ scss_compiler.py
└─ util.py
```
...
<!-- TABLE -- empty after DOM loaded, JS fills dynamically -->
<table id="table">
</table>
...
**`app/` The app directory is currently not in the repo but will be added as soon as the Electron app is available.**

**`web/` The web directory contains everything relevant to the web app.**

`.gitignore` The default git file that make sure no temporary files are getting uploaded to GitHub (e.g. `__pycache__/`).

`LICENSE` A simple license file.

`README.md` You are reading it right now.

`scss_compiler.py` A simple Python script that makes compiling SCSS to CSS easy during development.

`util.py` Utilities that are being used by the above Python script.

___

#### /web/
```sh
/web/
├─ public/
│ ├─ css/
│ │ └─ ...
│ │
│ ├─ img/
│ │ └─ ...
│ │
│ ├─ js/
│ │ └─ ...
│ │
│ ├─ scss/
│ │ └─ ...
│ │
│ └─ index.html
├─ .firebaserc
├─ README.md
└─ firebase.json
```
**`public/` This directory contains everything that is up on the host server.**

The **main.js** file is executed after the DOM has been loaded and populates the table.
This simply means, that it creates `<tr>` and `<td>` tags and inserts integers and strings.

See [Javascript](#javascript) for more detail.

### copyright
Well, each site needs a copyright line.

## SCSS
**main.scss** is pre-processed into **main.css**
The file is only included for completeness.

Both **main.scss** & **main.css** are kept up to date.

You **DON'T** need the main.scss for the website to work.
Think about it the same way as with hello.c and hello*.
`.firebaserc` Tells Firebase the associated project (not relevant for the app).

SCSS allows you for example to store rgb values or pixel values in variables at the top and SCSS will replace them within your CSS lines when it is compiled.
`README.md` Find more detail about the logic about the app.

It also allows for nesting elements inside of each other.
`firebase.json` The configuration file that tells Firebase what to deploy to the host server (not relevant for the app).

**SCSS**
```scss
$dark: rgb(48, 49, 48);
___

#element {
background-color: $dark;

p {
color: #ffffff;
}
}
```
**CSS**
```scss
#element {
background-color: rgb(48, 49, 48);
}

#element p {
color: #ffffff;
}
```

## Javascript
Alright, now it is getting fussy.

The JS code in this project is not focused on being clean and super efficient but rather making use of techniques and best practices learned in CS50.

It incorporates `Regular Expressions`, `User Input`, `for loops`, `extracting functions` and much more.

The `<table>` in the **index.html** is rendered empty. After the DOM is loaded, **main.js** populates it with columns and rows.

**HTML**
```html
<table id="table">
</table>
```
**JS**
```javascript
// get reference to HTML table tag
let table = document.getElementById("table");

// initialize table mode variable
// it is used by functions to for example copy a dec || hex integer
let mode = 'decimal';

/* SETUP TABLE */
function setup_table(command_mode) {

// setting mode to input if input conforms to options
if (command_mode.search(/^decimal|hexadecimal$/) != -1) {
mode = command_mode;
} else {
return;
}
...
}
```

This way, the table can be easily re-rendered to display hex codes instead of decimal codes when the user enteres a command.

As you can see, the `setup_table(command_mode)` function uses `Regular Expressions` to check if the argument conforms to possible modes.

Now, we won't go over every implementation detail. If you are interested, you can go into the source code yourself. It is very well documented with comments.

If you have question, feel free to ask me personally and not the CS50 staff, as they are not involved in this project.

### Populating the table
After we initialized `ascii_code_n` & `ascii_char_n` to empty arrays, we iterate over `0-127` (128 ASCII chars) and populate one column after the other.
Instead of hardcoding the `chars`, we convert the current `integer` (ASCII code) into the corresponding ASCII char.

**JS**
```javascript
// inside the setup_table() function
...

for (let number = 0; number < 128; number++) {
if (...) {

...

} else if (number < 64) {
if (mode === 'hexadecimal') {
let hex = '0x'.concat(number.toString(16));
ascii_code_3.push(hex);
} else {
ascii_code_3.push(number);
}
let char = String.fromCharCode(number);
ascii_char_3.push(char);
} else if (...) {

...

}
}

...
```
`number.toString(16)` converts an integer into a hexadecimal string. `65` becomes `41`.

By convention `'0x'.concat(...)` converts `65` into a more readable format `0x41`.

## Regular Expressions
Yeah, what everybody was waiting for!

ASCII50 makes use of **RE** for processing the command-line commands.
For example, triggering HEX mode does not only work with `ascii50 hexadecimal` but also `ascii50 hex`.
## Commands
As you might have realized, ASCII50 has its own command line... sort of.

Or in **RE** words: `/^ascii50\s+hex(adecimal)?$/i`
**Commands**
```sh
[dec, decimal] # Changes ASCII codes into decimal (base-10)

Check out the sourcecode for `main.js` to see the **RE** for getting the sourcecode.
[hex, hexadecimal] # Changes ASCII codes into hex (base-16)

A very helpful tool for figuring out **RE** is https://regex101.com.
[oct, octal] # Changes ASCII codes into octal (base-8)

## Commands
As you might have realized, ASCII50 has its own command line... sort of.
[bin, binary] # Changes ASCII codes into binary (base-2)

**Commands**
```
ascii50 hexadecimal (changes ASCII codes into hex)
[uhm, help] # Shows a short 'tutorial' for the tool

ascii50 decimal (changes ASCII codes into decimal)
[source, sourcecode, github] # Shows the source code

ascii50 sourcecode (shows the source code)
[matrix] # Follow the white rabbit

ascii50 matrix (blue pill or red pill?)
[buh] (👻)

... secret commands you said?
... Secret commands you said?
```
Loading

0 comments on commit 7fb7bb0

Please sign in to comment.