9 changed files with 322 additions and 314 deletions
@ -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). |
|
||||||
@ -1,9 +1,10 @@ |
|||||||
{ |
{ |
||||||
"compilerOptions": { |
"compilerOptions": { |
||||||
"target": "ES6", |
"target": "ES6", |
||||||
"module": "commonjs" |
"module": "commonjs" |
||||||
}, |
}, |
||||||
"exclude": [ |
"exclude": [ |
||||||
"node_modules" |
"node_modules", |
||||||
] |
"bin" |
||||||
|
] |
||||||
} |
} |
||||||
|
|||||||
@ -1,276 +1,271 @@ |
|||||||
.ui-border { |
.ui-border { |
||||||
border-radius: 3px; |
border-radius: 3px; |
||||||
border: 1px solid #333; |
border: 1px solid #333; |
||||||
} |
} |
||||||
|
|
||||||
a { |
a { |
||||||
border-bottom: 1px dotted; |
border-bottom: 1px dotted; |
||||||
text-decoration: none; |
text-decoration: none; |
||||||
color: #097; |
color: #097; |
||||||
} |
} |
||||||
|
|
||||||
a:hover { |
a:hover { |
||||||
color: #0a8; |
color: #0a8; |
||||||
} |
} |
||||||
|
|
||||||
a:visited { |
a:visited { |
||||||
color: #054; |
color: #054; |
||||||
} |
} |
||||||
|
|
||||||
#draft { |
#draft { |
||||||
margin-bottom: 3em; |
margin-bottom: 3em; |
||||||
} |
} |
||||||
|
|
||||||
.button { |
.button { |
||||||
cursor: pointer; |
cursor: pointer; |
||||||
} |
} |
||||||
|
|
||||||
.ui-elem { |
.ui-elem { |
||||||
background: #fff; |
background: #fff; |
||||||
font-size: 1em; |
font-size: 1em; |
||||||
opacity: 0.8; |
opacity: 0.8; |
||||||
padding: 0.3em; |
padding: 0.3em; |
||||||
border-radius: 3px; |
border-radius: 3px; |
||||||
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; |
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; |
||||||
font-weight: 300; |
font-weight: 300; |
||||||
border: 1px solid #333; |
border: 1px solid #333; |
||||||
} |
} |
||||||
|
|
||||||
.landing-button, |
.landing-button, |
||||||
textarea, |
textarea, |
||||||
fieldset { |
fieldset { |
||||||
border: none; |
border: none; |
||||||
} |
} |
||||||
|
|
||||||
.landing-button { |
.landing-button { |
||||||
padding: 10px; |
padding: 10px; |
||||||
border-radius: 10px; |
border-radius: 10px; |
||||||
background: #0a2; |
background: #0a2; |
||||||
font-size: 1.5em; |
font-size: 1.5em; |
||||||
text-decoration: none; |
text-decoration: none; |
||||||
box-shadow: 0 2px 5px #aaa; |
box-shadow: 0 2px 5px #aaa; |
||||||
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; |
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; |
||||||
font-weight: 300; |
font-weight: 300; |
||||||
} |
} |
||||||
|
|
||||||
.landing-button:hover { |
.landing-button:hover { |
||||||
background: #0b2; |
background: #0b2; |
||||||
} |
} |
||||||
|
|
||||||
.helvetica { |
.helvetica { |
||||||
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; |
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; |
||||||
font-weight: 300; |
font-weight: 300; |
||||||
} |
} |
||||||
|
|
||||||
#footer { |
#footer { |
||||||
text-align: center; |
text-align: center; |
||||||
padding-bottom: 1em; |
padding-bottom: 1em; |
||||||
font-size: 0.8em; |
font-size: 0.8em; |
||||||
width: 100%; |
width: 100%; |
||||||
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; |
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; |
||||||
font-weight: 300; |
font-weight: 300; |
||||||
} |
} |
||||||
|
|
||||||
@media screen and (max-width: 767px) { |
@media screen and (max-width: 767px) { |
||||||
#footer { |
#footer { |
||||||
font-size: 0.4em; |
font-size: 0.4em; |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
#footer a { |
#footer a { |
||||||
border: none; |
border: none; |
||||||
} |
} |
||||||
|
|
||||||
html, |
html, |
||||||
body { |
body { |
||||||
padding: 0; |
padding: 0; |
||||||
margin: 0; |
margin: 0; |
||||||
color: #333; |
color: #333; |
||||||
background: #fff; |
background: #fff; |
||||||
} |
} |
||||||
|
|
||||||
#hero { |
#hero { |
||||||
text-align: center; |
text-align: center; |
||||||
padding-bottom: 5em; |
padding-bottom: 5em; |
||||||
padding-top: 5em; |
padding-top: 5em; |
||||||
} |
} |
||||||
|
|
||||||
h1, |
h1, h2, h3, h4, h5, h6 { |
||||||
h2, |
font-family: Noticia Text, 'Noticia Text', 'PT Serif', 'Georgia'; |
||||||
h3, |
font-weight: bold; |
||||||
h4, |
} |
||||||
h5, |
|
||||||
h6 { |
h1 { |
||||||
font-family: Noticia Text, 'Noticia Text', 'PT Serif', 'Georgia'; |
font-size: 1.8em; |
||||||
font-weight: bold; |
} |
||||||
} |
|
||||||
|
h2 { |
||||||
h1 { |
font-size: 1.6em; |
||||||
font-size: 1.8em; |
} |
||||||
} |
|
||||||
|
h3 { |
||||||
h2 { |
font-size: 1.4em; |
||||||
font-size: 1.6em; |
} |
||||||
} |
|
||||||
|
h4 { |
||||||
h3 { |
font-size: 1.2em; |
||||||
font-size: 1.4em; |
} |
||||||
} |
|
||||||
|
h5 { |
||||||
h4 { |
font-size: 1.1em; |
||||||
font-size: 1.2em; |
} |
||||||
} |
|
||||||
|
h6 { |
||||||
h5 { |
font-size: 1.0em; |
||||||
font-size: 1.1em; |
} |
||||||
} |
|
||||||
|
#hero h1 { |
||||||
h6 { |
font-size: 2.5em; |
||||||
font-size: 1.0em; |
} |
||||||
} |
|
||||||
|
#hero h2 { |
||||||
#hero h1 { |
margin: 2em; |
||||||
font-size: 2.5em; |
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; |
||||||
} |
font-weight: 300; |
||||||
|
} |
||||||
#hero h2 { |
|
||||||
margin: 2em; |
article { |
||||||
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; |
-webkit-flex: 1; |
||||||
font-weight: 300; |
flex: 1; |
||||||
} |
text-align: justify; |
||||||
|
margin-top: 5em; |
||||||
article { |
font-family: Georgia, 'Georgia'; |
||||||
-webkit-flex: 1; |
margin-right: auto; |
||||||
flex: 1; |
margin-left: auto; |
||||||
text-align: justify; |
} |
||||||
margin-top: 5em; |
|
||||||
font-family: Georgia, 'Georgia'; |
@media screen and (min-width: 1024px) { |
||||||
margin-right: auto; |
article { |
||||||
margin-left: auto; |
width: 800px; |
||||||
} |
} |
||||||
|
} |
||||||
@media screen and (min-width: 1024px) { |
|
||||||
article { |
@media screen and (max-width: 1023px) { |
||||||
width: 800px; |
article { |
||||||
} |
width: 90%; |
||||||
} |
} |
||||||
|
} |
||||||
@media screen and (max-width: 1023px) { |
|
||||||
article { |
.central-element { |
||||||
width: 90%; |
margin-right: auto; |
||||||
} |
margin-left: auto; |
||||||
} |
} |
||||||
|
|
||||||
.central-element { |
@media screen and (min-width: 1024px) { |
||||||
margin-right: auto; |
.central-element { |
||||||
margin-left: auto; |
width: 800px; |
||||||
} |
} |
||||||
|
} |
||||||
@media screen and (min-width: 1024px) { |
|
||||||
.central-element { |
@media screen and (max-width: 1023px) { |
||||||
width: 800px; |
.central-element { |
||||||
} |
width: 90%; |
||||||
} |
} |
||||||
|
} |
||||||
@media screen and (max-width: 1023px) { |
|
||||||
.central-element { |
article img { |
||||||
width: 90%; |
max-width: 100%; |
||||||
} |
} |
||||||
} |
|
||||||
|
article p { |
||||||
article img { |
line-height: 140%; |
||||||
max-width: 100%; |
font-size: 1.2em; |
||||||
} |
} |
||||||
|
|
||||||
article p { |
article > h1:first-child { |
||||||
line-height: 140%; |
margin: 2em; |
||||||
font-size: 1.2em; |
font-size: 2.0em; |
||||||
} |
text-align: center; |
||||||
|
} |
||||||
article > h1:first-child { |
|
||||||
margin: 2em; |
.centered { |
||||||
font-size: 2.0em; |
text-align: center; |
||||||
text-align: center; |
} |
||||||
} |
|
||||||
|
.bottom-space { |
||||||
.centered { |
margin-bottom: 7em; |
||||||
text-align: center; |
} |
||||||
} |
|
||||||
|
code, |
||||||
.bottom-space { |
pre { |
||||||
margin-bottom: 7em; |
font-size: 1.2em; |
||||||
} |
background: #efefef; |
||||||
|
font-family: monospace; |
||||||
code, |
} |
||||||
pre { |
|
||||||
font-size: 1.2em; |
pre { |
||||||
background: #efefef; |
border: 1px dotted#888; |
||||||
font-family: monospace; |
padding: 0.5em; |
||||||
} |
border-radius: 3px; |
||||||
|
} |
||||||
pre { |
|
||||||
border: 1px dotted#888; |
*:focus { |
||||||
padding: 0.5em; |
outline: 0px none transparent; |
||||||
border-radius: 3px; |
} |
||||||
} |
|
||||||
|
@media screen and (min-width: 1024px) { |
||||||
*:focus { |
textarea { |
||||||
outline: 0px none transparent; |
width: 800px; |
||||||
} |
} |
||||||
|
} |
||||||
@media screen and (min-width: 1024px) { |
|
||||||
textarea { |
textarea { |
||||||
width: 800px; |
height: 500px; |
||||||
} |
font-size: 1em; |
||||||
} |
font-family: Courier; |
||||||
|
border-radius: 5px; |
||||||
textarea { |
} |
||||||
height: 500px; |
|
||||||
font-size: 1em; |
.hidden { |
||||||
font-family: Courier; |
display: none; |
||||||
border-radius: 5px; |
} |
||||||
} |
|
||||||
|
#dashed-line { |
||||||
.hidden { |
margin-bottom: 3em; |
||||||
display: none; |
margin-top: 3em; |
||||||
} |
border-bottom: 1px dashed#888; |
||||||
|
} |
||||||
#dashed-line { |
|
||||||
margin-bottom: 3em; |
table { |
||||||
margin-top: 3em; |
border-collapse: collapse; |
||||||
border-bottom: 1px dashed#888; |
width: 100%; |
||||||
} |
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; |
||||||
|
font-weight: 300; |
||||||
table { |
} |
||||||
border-collapse: collapse; |
|
||||||
width: 100%; |
th { |
||||||
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', 'sans-serif'; |
background-color: #efefef; |
||||||
font-weight: 300; |
line-height: 2.5em; |
||||||
} |
padding: 0.3em; |
||||||
|
} |
||||||
th { |
|
||||||
background-color: #efefef; |
td { |
||||||
line-height: 2.5em; |
line-height: 2.5em; |
||||||
padding: 0.3em; |
padding: 0.3em; |
||||||
} |
border-top: 1px dotted#888; |
||||||
|
} |
||||||
td { |
|
||||||
line-height: 2.5em; |
.middot { |
||||||
padding: 0.3em; |
padding: 0.5em; |
||||||
border-top: 1px dotted#888; |
} |
||||||
} |
|
||||||
|
body { |
||||||
.middot { |
display: -webkit-flex; |
||||||
padding: 0.5em; |
} |
||||||
} |
|
||||||
|
body { |
||||||
body { |
-webkit-flex-direction: column; |
||||||
display: -webkit-flex; |
flex-direction: column; |
||||||
} |
display: flex; |
||||||
|
min-height: 100vh; |
||||||
body { |
} |
||||||
-webkit-flex-direction: column; |
|
||||||
flex-direction: column; |
|
||||||
display: flex; |
|
||||||
min-height: 100vh; |
|
||||||
} |
|
||||||
@ -0,0 +1,16 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html> |
||||||
|
<head> |
||||||
|
<title>NoteHub — %TITLE%</title> |
||||||
|
<meta charset="UTF-8"> |
||||||
|
<meta content="width=device-width, initial-scale=1.0" name="viewport"> |
||||||
|
<link href="https://fonts.googleapis.com/css?family=PT+Serif:700|Noticia+Text:700&subset=latin,cyrillic" |
||||||
|
rel="stylesheet" type="text/css" /> |
||||||
|
<link href="style.css" rel="stylesheet" type="text/css" /> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<article> |
||||||
|
%CONTENT% |
||||||
|
</article> |
||||||
|
</body> |
||||||
|
</html> |
||||||
@ -1,17 +1,13 @@ |
|||||||
var express = require('express'); |
var express = require('express'); |
||||||
|
var page = require('./bin/page'); |
||||||
var app = express(); |
var app = express(); |
||||||
|
|
||||||
/* |
|
||||||
app.get('/', function (req, res) { |
|
||||||
res.send('Hello World!'); |
|
||||||
}); |
|
||||||
*/ |
|
||||||
|
|
||||||
app.use(express.static(__dirname + '/resources/public')); |
app.use(express.static(__dirname + '/resources/public')); |
||||||
|
|
||||||
var server = app.listen(3000, function () { |
app.get('/api', function (req, res) { |
||||||
var host = server.address().address; |
res.send(page.build("api")); |
||||||
var port = server.address().port; |
}); |
||||||
|
|
||||||
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); |
||||||
}); |
}); |
||||||
@ -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; |
||||||
|
}; |
||||||
Loading…
Reference in new issue