From b2b383b941047073ed8d8b35c9b27519c9d0c9f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20M=C3=BCller?= Date: Mon, 17 Aug 2015 09:19:08 +0200 Subject: [PATCH] page builder module started --- API.md | 8 +- LANDING.md | 19 -- jsconfig.json | 9 +- package.json | 5 +- resources/public/style.css | 545 ++++++++++++++++++------------------- resources/template.html | 16 ++ server.js | 16 +- src/index.js | 1 - src/page.js | 17 ++ 9 files changed, 322 insertions(+), 314 deletions(-) delete mode 100644 LANDING.md create mode 100644 resources/template.html delete mode 100644 src/index.js create mode 100644 src/page.js diff --git a/API.md b/API.md index fad729a..299098e 100644 --- a/API.md +++ b/API.md @@ -31,10 +31,10 @@ A simple `GET` request to the following URL: with the following parameters: -Parameter | Explanation | Type ---- | --- | --- -`noteID` | Note-ID | **required** -`version` | Used API version | **required** +Parameter | Explanation | Type +--- | --- | --- +`noteID` | Note-ID | **required** +`version` | Used API version | **required** will return a JSON object containing following self explaining fields: `note`, `title`, `longURL`, `shortURL`, `statistics`, `status`, `publisher`. diff --git a/LANDING.md b/LANDING.md deleted file mode 100644 index 7a148a5..0000000 --- a/LANDING.md +++ /dev/null @@ -1,19 +0,0 @@ -## Features -- **Themes**: specify the color scheme in the URL: [default](/2014/3/31/demo-note), [dark](/2014/3/31/demo-note?theme=dark), [solarized light](/2014/3/31/demo-note?theme=solarized-light), [solarized dark](/2014/3/31/demo-note?theme=solarized-dark). -- **Fonts**: specify a font (e.g., [Google Web Fonts](http://www.google.com/webfonts/)) for headers and body text in the URL like [this](/8m4l9) or [this](/2014/3/31/demo-note?text-font=monospace&header-font=Courier&text-size=0.7&header-size=1.1). -- **Short URLs**: every page (including theme & font options) has its own short url. -- **Editing**: if you set a password during publishing, you can edit your note any time later. -- **Statistics**: page view counter, publishing and editing date. -- **Expiration**: all notes with less than 30 views after the first 30 days will expire. -- **Export**: the original markdown content can be displayed in plain text format. -- **API**: Integrate the publishing functionality into your editor using the official [NoteHub API](/api). - -## Changelog - - **2014-09**: text size setting added ([example](/2014/3/31/demo-note?text-font=monospace&header-font=Courier&text-size=0.7&header-size=1.1)) - - **2014-07**: deprecated all API versions less than 1.4 & performance improvements. - - **2014-03**: note expiration implemented. - - **2014-02**: a simple JS-client for API testing [added](/api-test.html). - - **2014-01**: [NoteHub API](/api), mobile friendly styling and more. - - **2013-03**: new color themes. - - **2012-07**: password protection for note editing added. - - **2012-06**: NoteHub released as a result of an [experiment](/2012/6/16/how-notehub-is-built). diff --git a/jsconfig.json b/jsconfig.json index 7ffced7..ca5b5e3 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -1,9 +1,10 @@ { "compilerOptions": { "target": "ES6", - "module": "commonjs" + "module": "commonjs" }, - "exclude": [ - "node_modules" - ] + "exclude": [ + "node_modules", + "bin" + ] } diff --git a/package.json b/package.json index 378c4d0..865a68b 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "main": "server.js", "scripts": { "server": "node server.js", + "devser": "nodemon server.js", "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { @@ -22,6 +23,8 @@ }, "homepage": "https://github.com/chmllr/NoteHub", "dependencies": { - "express": "^4.13.3" + "express": "^4.13.3", + "lru-cache": "^2.6.5", + "marked": "^0.3.5" } } diff --git a/resources/public/style.css b/resources/public/style.css index 6fca012..b444508 100644 --- a/resources/public/style.css +++ b/resources/public/style.css @@ -1,276 +1,271 @@ .ui-border { - border-radius: 3px; - border: 1px solid #333; - } - - a { - border-bottom: 1px dotted; - text-decoration: none; - color: #097; - } - - a:hover { - color: #0a8; - } - - a:visited { - color: #054; - } - - #draft { - margin-bottom: 3em; - } - - .button { - cursor: pointer; - } - - .ui-elem { - background: #fff; - font-size: 1em; - opacity: 0.8; - padding: 0.3em; - border-radius: 3px; - font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; - font-weight: 300; - border: 1px solid #333; - } - - .landing-button, - textarea, - fieldset { - border: none; - } - - .landing-button { - padding: 10px; - border-radius: 10px; - background: #0a2; - font-size: 1.5em; - text-decoration: none; - box-shadow: 0 2px 5px #aaa; - font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; - font-weight: 300; - } - - .landing-button:hover { - background: #0b2; - } - - .helvetica { - font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; - font-weight: 300; - } - - #footer { - text-align: center; - padding-bottom: 1em; - font-size: 0.8em; - width: 100%; - font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; - font-weight: 300; - } - - @media screen and (max-width: 767px) { - #footer { - font-size: 0.4em; - } - } - - #footer a { - border: none; - } - - html, - body { - padding: 0; - margin: 0; - color: #333; - background: #fff; - } - - #hero { - text-align: center; - padding-bottom: 5em; - padding-top: 5em; - } - - h1, - h2, - h3, - h4, - h5, - h6 { - font-family: Noticia Text, 'Noticia Text', 'PT Serif', 'Georgia'; - font-weight: bold; - } - - h1 { - font-size: 1.8em; - } - - h2 { - font-size: 1.6em; - } - - h3 { - font-size: 1.4em; - } - - h4 { - font-size: 1.2em; - } - - h5 { - font-size: 1.1em; - } - - h6 { - font-size: 1.0em; - } - - #hero h1 { - font-size: 2.5em; - } - - #hero h2 { - margin: 2em; - font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; - font-weight: 300; - } - - article { - -webkit-flex: 1; - flex: 1; - text-align: justify; - margin-top: 5em; - font-family: Georgia, 'Georgia'; - margin-right: auto; - margin-left: auto; - } - - @media screen and (min-width: 1024px) { - article { - width: 800px; - } - } - - @media screen and (max-width: 1023px) { - article { - width: 90%; - } - } - - .central-element { - margin-right: auto; - margin-left: auto; - } - - @media screen and (min-width: 1024px) { - .central-element { - width: 800px; - } - } - - @media screen and (max-width: 1023px) { - .central-element { - width: 90%; - } - } - - article img { - max-width: 100%; - } - - article p { - line-height: 140%; - font-size: 1.2em; - } - - article > h1:first-child { - margin: 2em; - font-size: 2.0em; - text-align: center; - } - - .centered { - text-align: center; - } - - .bottom-space { - margin-bottom: 7em; - } - - code, - pre { - font-size: 1.2em; - background: #efefef; - font-family: monospace; - } - - pre { - border: 1px dotted#888; - padding: 0.5em; - border-radius: 3px; - } - - *:focus { - outline: 0px none transparent; - } - - @media screen and (min-width: 1024px) { - textarea { - width: 800px; - } - } - - textarea { - height: 500px; - font-size: 1em; - font-family: Courier; - border-radius: 5px; - } - - .hidden { - display: none; - } - - #dashed-line { - margin-bottom: 3em; - margin-top: 3em; - border-bottom: 1px dashed#888; - } - - table { - border-collapse: collapse; - width: 100%; - font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; - font-weight: 300; - } - - th { - background-color: #efefef; - line-height: 2.5em; - padding: 0.3em; - } - - td { - line-height: 2.5em; - padding: 0.3em; - border-top: 1px dotted#888; - } - - .middot { - padding: 0.5em; - } - - body { - display: -webkit-flex; - } - - body { - -webkit-flex-direction: column; - flex-direction: column; - display: flex; - min-height: 100vh; - } \ No newline at end of file + border-radius: 3px; + border: 1px solid #333; +} + +a { + border-bottom: 1px dotted; + text-decoration: none; + color: #097; +} + +a:hover { + color: #0a8; +} + +a:visited { + color: #054; +} + +#draft { + margin-bottom: 3em; +} + +.button { + cursor: pointer; +} + +.ui-elem { + background: #fff; + font-size: 1em; + opacity: 0.8; + padding: 0.3em; + border-radius: 3px; + font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; + font-weight: 300; + border: 1px solid #333; +} + +.landing-button, +textarea, +fieldset { + border: none; +} + +.landing-button { + padding: 10px; + border-radius: 10px; + background: #0a2; + font-size: 1.5em; + text-decoration: none; + box-shadow: 0 2px 5px #aaa; + font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; + font-weight: 300; +} + +.landing-button:hover { + background: #0b2; +} + +.helvetica { + font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; + font-weight: 300; +} + +#footer { + text-align: center; + padding-bottom: 1em; + font-size: 0.8em; + width: 100%; + font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; + font-weight: 300; +} + +@media screen and (max-width: 767px) { + #footer { + font-size: 0.4em; + } +} + +#footer a { + border: none; +} + +html, +body { + padding: 0; + margin: 0; + color: #333; + background: #fff; +} + +#hero { + text-align: center; + padding-bottom: 5em; + padding-top: 5em; +} + +h1, h2, h3, h4, h5, h6 { + font-family: Noticia Text, 'Noticia Text', 'PT Serif', 'Georgia'; + font-weight: bold; +} + +h1 { + font-size: 1.8em; +} + +h2 { + font-size: 1.6em; +} + +h3 { + font-size: 1.4em; +} + +h4 { + font-size: 1.2em; +} + +h5 { + font-size: 1.1em; +} + +h6 { + font-size: 1.0em; +} + +#hero h1 { + font-size: 2.5em; +} + +#hero h2 { + margin: 2em; + font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; + font-weight: 300; +} + +article { + -webkit-flex: 1; + flex: 1; + text-align: justify; + margin-top: 5em; + font-family: Georgia, 'Georgia'; + margin-right: auto; + margin-left: auto; +} + +@media screen and (min-width: 1024px) { + article { + width: 800px; + } +} + +@media screen and (max-width: 1023px) { + article { + width: 90%; + } +} + +.central-element { + margin-right: auto; + margin-left: auto; +} + +@media screen and (min-width: 1024px) { + .central-element { + width: 800px; + } +} + +@media screen and (max-width: 1023px) { + .central-element { + width: 90%; + } +} + +article img { + max-width: 100%; +} + +article p { + line-height: 140%; + font-size: 1.2em; +} + +article > h1:first-child { + margin: 2em; + font-size: 2.0em; + text-align: center; +} + +.centered { + text-align: center; +} + +.bottom-space { + margin-bottom: 7em; +} + +code, +pre { + font-size: 1.2em; + background: #efefef; + font-family: monospace; +} + +pre { + border: 1px dotted#888; + padding: 0.5em; + border-radius: 3px; +} + +*:focus { + outline: 0px none transparent; +} + +@media screen and (min-width: 1024px) { + textarea { + width: 800px; + } +} + +textarea { + height: 500px; + font-size: 1em; + font-family: Courier; + border-radius: 5px; +} + +.hidden { + display: none; +} + +#dashed-line { + margin-bottom: 3em; + margin-top: 3em; + border-bottom: 1px dashed#888; +} + +table { + border-collapse: collapse; + width: 100%; + font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; + font-weight: 300; +} + +th { + background-color: #efefef; + line-height: 2.5em; + padding: 0.3em; +} + +td { + line-height: 2.5em; + padding: 0.3em; + border-top: 1px dotted#888; +} + +.middot { + padding: 0.5em; +} + +body { + display: -webkit-flex; +} + +body { + -webkit-flex-direction: column; + flex-direction: column; + display: flex; + min-height: 100vh; +} \ No newline at end of file diff --git a/resources/template.html b/resources/template.html new file mode 100644 index 0000000..d564c15 --- /dev/null +++ b/resources/template.html @@ -0,0 +1,16 @@ + + + + NoteHub — %TITLE% + + + + + + +
+ %CONTENT% +
+ + \ No newline at end of file diff --git a/server.js b/server.js index 2fc9e65..bd9eee4 100644 --- a/server.js +++ b/server.js @@ -1,17 +1,13 @@ var express = require('express'); +var page = require('./bin/page'); var app = express(); -/* -app.get('/', function (req, res) { - res.send('Hello World!'); -}); -*/ - app.use(express.static(__dirname + '/resources/public')); -var server = app.listen(3000, function () { - var host = server.address().address; - var port = server.address().port; +app.get('/api', function (req, res) { + res.send(page.build("api")); +}); - console.log('NoteHub server listening at http://%s:%s', host, port); +var server = app.listen(3000, function () { + console.log('NoteHub server listening on port %s', server.address().port); }); \ No newline at end of file diff --git a/src/index.js b/src/index.js deleted file mode 100644 index 3f25a1c..0000000 --- a/src/index.js +++ /dev/null @@ -1 +0,0 @@ -var f = () => console.log("hello world!"); \ No newline at end of file diff --git a/src/page.js b/src/page.js new file mode 100644 index 0000000..e719ad8 --- /dev/null +++ b/src/page.js @@ -0,0 +1,17 @@ +var LRU = require("lru-cache"), + marked = require("marked"), + fs = require("fs"); + +var CACHE = new LRU(30); // create LRU cache of size 30 +var template = fs.readFileSync("resources/template.html", "utf-8"); +var buildHTML = (title, content) => template + .replace("%TITLE%", title) + .replace("%CONTENT%", content); +var apiPage = buildHTML("API", marked(fs.readFileSync("API.md", "utf-8"))); + +export var build = id => { + if (CACHE.has(id)) return CACHE.get(id); + var content = id == "api" ? apiPage : "This is page " + id; + CACHE.set(id, content); + return content; +};