diff options
-rw-r--r-- | static/css/main.css | 151 | ||||
-rw-r--r-- | static/js/lang.js | 4 | ||||
-rw-r--r-- | static/js/main.js | 73 |
3 files changed, 212 insertions, 16 deletions
diff --git a/static/css/main.css b/static/css/main.css index 696faf6..8bb8b6d 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -5,12 +5,13 @@ html { font-size: 18px; } -/* layout */ +/* resets */ html, body { --block-accent-color: #e02345; margin: 0; + background: #f8f5f5; } main { @@ -26,9 +27,157 @@ h3 { font-family: var(--ff-tabloid); font-weight: normal; color: var(--block-accent-color); + margin: .5rem 0; +} + +p { + margin-top: .5em; + margin-bottom: 1em; } +button { + font-size: 1em; +} + +code, input, textarea { font-family: var(--ff-mono); } + +/* layout */ + +header, +footer { + text-align: center; + display: flex; + flex-direction: column; + align-items: center; + margin-bottom: 3em; +} + +nav { + margin: .8em 0; +} + +nav a { + color: var(--block-accent-color); + margin: 0 1em; +} + +header .subtitle { + font-size: 1.2em; +} + +header .lang.block { + --block-background-color: #000; + + font-size: 1.4em; + font-family: var(--ff-tabloid); + font-weight: normal; + color: #fff; + display: inline-block; /* for transforms */ + transform: rotate(-10deg); + pointer-events: none; +} + +.editor { + display: flex; + flex-direction: column; + position: relative; + margin-bottom: 3em; +} + +.editor .code, +.editor .output, +.editor .errors { + width: 100%; + padding: .5em 1em; + border-bottom: 3px solid var(--block-text-color); + box-sizing: border-box; +} + +.editor > :last-child { + border-bottom: 0; +} + +.editor.block { + padding: 0; +} + +.editor .controls { + position: absolute; + top: -24px; + right: 0; + width: 100%; + box-sizing: border-box; + padding: 0 1em; + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-end; +} + +.editor .output { + min-height: 5em; + display: flex; + flex-direction: column; + align-items: flex-start; + line-height: 1.5em; +} + +.editor .output .output-line { + width: 100%; +} + +.editor .code { + padding: 0; + position: relative; +} + +.editor .errors { + color: var(--block-accent-color); +} + +.filler, +textarea.editor-input { + font-family: var(--ff-mono); + font-size: 1em; + line-height: 1.3em; + padding: .5em 1em; + border: 0; + width: 100%; + box-sizing: border-box; + overflow-y: auto; + resize: none; + white-space: nowrap; +} + +textarea.editor-input { + position: absolute; + background: var(--block-background-color); + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +textarea.editor-input:focus { + outline: none; + background: #f8f8f8; +} + +.filler p { + margin: 0; + padding: 0; + word-wrap: break-word; + white-space: pre-wrap; +} + +.output .no-output { + color: #777; +} + +footer a { + color: var(--block-accent-color); +} diff --git a/static/js/lang.js b/static/js/lang.js index 4d17b48..08e1499 100644 --- a/static/js/lang.js +++ b/static/js/lang.js @@ -47,7 +47,7 @@ class Reader { */ class Wordifier { constructor(str) { - this.reader = new Reader(str); + this.reader = new Reader(str.trim()); this.tokens = []; } wordify() { @@ -83,7 +83,7 @@ class Wordifier { } this.reader.dropWhitespace(); } - return this.tokens.slice(1); + return this.tokens; } wordifyString(endChar) { let acc = ''; diff --git a/static/js/main.js b/static/js/main.js index b6aa634..3815538 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -1,5 +1,4 @@ -const PROG_DEFAULT = ` -DISCOVER HOW TO factorial WITH n +const PROG_DEFAULT = `DISCOVER HOW TO factorial WITH n WE SAID WHAT IF n IS ACTUALLY 0 WE SAID @@ -16,6 +15,18 @@ YOU WON'T WANT TO MISS result PLEASE LIKE AND SUBSCRIBE`; +const HEADLINES = [ + `You Won't Believe What This Programming Language Can Do!`, + `The Best Programming Language You Haven't Heard Of (It Will Surprise You!)`, + `Shocking New Programming Language Bewilders Programmers at Google and Facebook!`, + `Programmer Who Made Everything Now Predicts the Next Big Language!`, + `The Secret Programming Language Every 10x Programmer Recommends!`, +]; + +function randomHeadline() { + return HEADLINES[~~(Math.random() * HEADLINES.length)]; +} + const { Component, } = window.Torus; @@ -28,6 +39,10 @@ class Editor extends Component { this.errors = ''; this.handleRun = () => this.eval(); + this.handleReset = () => { + this.prog = PROG_DEFAULT; + this.render(); + } this.handleInput = evt => { this.prog = evt.target.value; this.render(); @@ -35,12 +50,13 @@ class Editor extends Component { } eval() { this.output = ''; + this.errors = ''; try { const tokens = tokenize(this.prog); const nodes = new Parser(tokens).parse(); const env = new Environment({ print: s => { - this.output += s.toString(); + this.output += s.toString() + '\n'; this.render(); }, }); @@ -53,23 +69,31 @@ class Editor extends Component { compose() { return jdom`<div class="editor fixed block"> <div class="controls"> + ${this.prog === PROG_DEFAULT ? null : + jdom`<button class="block" + onclick=${this.handleReset}>Reset</button>`} <button class="accent block" onclick=${this.handleRun}>Run!</button> </div> <div class="code"> - <textarea cols="30" rows="10" + <div class="filler"> + ${this.prog.split('\n') + .map(line => jdom`<p>${line.trim() ? line : '-'}</p>`)} + </div> + <textarea class="editor-input" cols="30" rows="10" value=${this.prog} oninput=${this.handleInput}> </textarea> </div> - <div class="result"> - <div class="output"> - ${this.output.split('\n').map(line => jdom`<code>${line}</code>`)} - </div> - <div class="errors"> - ${this.errors.split('\n').map(line => jdom`<code>${line}</code>`)} - </div> + <div class="output"> + ${this.output ? this.output + .split('\n') + .map(line => jdom`<code class="output-line">${line}</code>`) + : jdom`<code class="no-output">No output.</code>`} </div> + ${this.errors ? jdom`<div class="errors"> + ${this.errors.split('\n').map(line => jdom`<code>${line}</code>`)} + </div>` : null} </div>`; } } @@ -80,9 +104,32 @@ class App extends Component { } compose() { return jdom`<main> - <h1>Tabloid</h1> - <p class="subtitle">The Clickbait Headline Programming Language</p> + <header> + <h1>${randomHeadline()}</h1> + <nav> + <a href="https://github.com/thesephist/tabloid" + target="_blank" noopener noreferer>GitHub</a> + <a href="https://dotink.co/posts/tabloid/" + target="_blank" noopener noreferer>Blog post</a> + </nav> + <p class="subtitle"> + <strong class="lang fixed inline block">Tabloid:</strong> The Clickbait Headline Programming Language + </p> + </header> ${this.editor.node} + <h2>What?</h2> + <h2>But why?</h2> + <h2>Does it actually work?</h2> + <footer> + <p> + Tabloid is a project by + <a href="https://thesephist.com/">@thesephist</a>, + website built with + <a href="https://github.com/thesephist/torus">Torus</a> + and + <a href="https://thesephist.github.io/blocks.css/">blocks.css</a>. + </p> + </footer> </main>`; } } |