Browse Source

plain text hidden behind a function call (to make localization easier)

master
Christian Mueller 14 years ago
parent
commit
01754a7d57
  1. 26
      messages
  2. 1
      project.clj
  3. 9
      src/NoteHub/crossover/lib.clj
  4. 26
      src/NoteHub/settings.clj
  5. 1
      src/NoteHub/storage.clj
  6. 3
      src/NoteHub/views/common.clj
  7. 19
      src/NoteHub/views/css_generator.clj
  8. 90
      src/NoteHub/views/pages.clj

26
messages

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
title = Free and Hassle-free Markdown Hosting.
name = NoteHub
new-page = New Page
column-why = Why?
column-why-long = Not every person, who occasionally wants to express some thoughts, needs a blog. Blogs are __tedious__ for writers and for readers. Most people are not interested in thoughts of other random people. Moreover, nowadays everything rotates around social networks and not individual blogs. It makes much more sense to publish something somewhere and to share the link with the audience on the community or social network of your choice, than to maintain a blog trying to keep your readers interested. __NoteHub__ should be the place, where you can publish your thoughts without hassle.
column-how = How to Use?
column-how-long = First [create](/new) a new page using the [Markdown](http://daringfireball.net/projects/markdown/) syntax. Now, besides just sharing the link, you can view some rudimentary statistics by appending `/stats` to the note url: <pre>notehub.org/.../title/stats</pre> If you want to export a note in the original Markdown format, append `/export`: <pre>notehub.org/.../title/export</pre> You also can invert the color scheme by appending `?theme=dark` to the note url: <pre>notehub.org/.../title?theme=dark</pre>
column-geeks = For Geeks!
column-geeks-long = NoteHub was an one-app-one-language experiment and is implemented entirely in [Clojure](http://clojure.org) and ClojureScript. Its [source code](https://github.com/chmllr/NoteHub) can be found on GitHub. Look at the code to find some undocumented NoteHub features (or bugs) and &mdash; feel free to contribute! (If you are interested in more detailed code overview, read [this note](http://notehub.org).) NoteHub's design is intentionally kept extremelly simple and minimalistic, and should stay like this. NoteHub's persistence layer bases on the key-value store [redis](http://redis.io). Currently, NoteHub is hosted for free on [Heroku](http://heroku.com). Send your feedback and comments directly to [@chmllr](http://twitter.com/chmllr) or [open an issue](https://github.com/chmllr/NoteHub/issues) on GitHub.
status-404 = Nothing found.
status-400 = Bad Request.
status-500 = OMG, Server Exploded.
created-by = Created by [@chmllr](http://twitter.com/chmllr)
loading = Loading...
preview = Preview
publish = Publish
published = Published
article-views = Article Views
statistics = Statistics
new-note = New Markdown Note

1
project.clj

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
(defproject NoteHub "0.1.0-SNAPSHOT"
:description "A free and anonymous hosting for markdown pages."
:dependencies [[org.clojure/clojure "1.4.0"]
[org.clojure/clojure-contrib "1.2.0"]
[hiccup "1.0.0"]
[cssgen "0.2.6"]
[jayq "0.1.0-alpha2"]

9
src/NoteHub/crossover/lib.clj

@ -4,15 +4,16 @@ @@ -4,15 +4,16 @@
(defn hash
"A simple hash-function, which computes a hash from the text field
content and given session number. It is intended to be used as a spam
protection / captcha alternative. (Probably doesn't work for URF-16)"
protection / captcha alternative (let's see whether spambots evaluate heavy JS).
(Probably doesn't work for UTF-16)"
[f s]
(let [short-mod #(mod % 32767)
char-codes (map f
(filter #(not (contains? #{"\n" "\r"} %)) (map str s)))]
char-codes (map f (remove #(contains? #{"\n" "\r"} %) (map str s)))
zip-with-index (map list char-codes (range))]
(reduce
#(short-mod (+ %
(short-mod (* (first %2)
((if (odd? %)
bit-xor
bit-and) 16381 (second %2))))))
0 (map list char-codes (range)))))
0 zip-with-index)))

26
src/NoteHub/settings.clj

@ -1,19 +1,33 @@ @@ -1,19 +1,33 @@
(ns NoteHub.settings
(:require [clojure.contrib.string :as ccs])
(:refer-clojure :exclude [replace reverse])
(:use [clojure.string]))
; Load and parse te settings file returning a map
(def settings-map
(let [file-content (slurp "settings")
lines (split file-content #"\n")
pairs (map #(map trim (split % #"=")) lines)]
; Loads and parses the settings file; returns a key-value map.
; Assumes, that all string of the setings file are in format:
; key = value
(defn- get-pairs-map [file]
(let [file-content (slurp file)
pairs (map #(map trim (split % #"=" 2))
(remove ccs/blank? (ccs/split-lines file-content)))]
(apply hash-map
(mapcat #(list (keyword (first %)) (second %)) pairs))))
(def settings-map
(get-pairs-map "settings"))
(def messages-map
(get-pairs-map "messages"))
(defn get-message [key]
"Returns messages used in layouts. Every key should be a keyword, e.g. (get-message :title)."
(messages-map key))
(defn get-setting
"Takes a settings key, a converter function and a default value, and returns a corresponding
setting value. The default value is returned back when no setting value was found.
The converter function can be provided to convert the setting from string to a needed type."
The converter function can be provided to convert the setting from string to a needed type.
Every key should be a keyword, e.g. (get-setting :page-width)."
[key & more]
(let [converter (first more)
default (second more)

1
src/NoteHub/storage.clj

@ -13,7 +13,6 @@ @@ -13,7 +13,6 @@
(def note "note")
(def views "views")
; Concatenates all fields to a string
(defn- build-key [[year month day] title]
(print-str year month day title))

3
src/NoteHub/views/common.clj

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
(ns NoteHub.views.common
(:use
[NoteHub.settings :only [get-message]]
[NoteHub.views.css-generator]
[noir.core :only [defpartial]]
[hiccup.page :only [include-js html5]]
@ -10,7 +11,7 @@ @@ -10,7 +11,7 @@
[params title & content]
(html5
[:head
[:title "NoteHub &mdash; " title]
[:title (print-str (get-message :name) "&mdash;" title)]
[:link {:href
(clojure.string/replace
(str "http://fonts.googleapis.com/css?family="

19
src/NoteHub/views/css_generator.clj

@ -54,12 +54,19 @@ @@ -54,12 +54,19 @@
background-halftone (color theme :background-halftone)
foreground-halftone (color theme :foreground-halftone)]
(css
(rule "a"
:color :#097
:text-decoration :none
:border-bottom [:1px :dotted]
(rule "&:hover"
:color :#0a8)
(rule "&:visited"
:color :#054))
(rule ".landing-button"
:box-shadow [0 :2px :5px :#aaa]
:text-decoration :none
:font-size :1.5em
:background :#0a2
:color :white
:border :none
:border-radius :10px
:padding :10px
@ -77,6 +84,7 @@ @@ -77,6 +84,7 @@
(rule "td"
:padding :0.5em)
(rule ".one-third-column"
:line-height (% 120)
:text-align :justify
:vertical-align :top
; Replace this by arithmetic with css-lengths as soon as they fix the bug
@ -94,16 +102,19 @@ @@ -94,16 +102,19 @@
:margin :2em))
(rule "article"
central-element
:line-height (% 140)
:font-family text-fonts
:text-align :justify
:font-size :1.2em
(rule "p"
:line-height (% 140))
(rule "& > h1:first-child"
:text-align :center
:margin :2em))
(rule ".centered"
:text-align :center)
(rule "pre"
:border-radius :3px
:padding :1em
:padding :0.5em
:border [:1px :dotted foreground-halftone]
:background background-halftone)
(rule "*:focus"
@ -129,7 +140,7 @@ @@ -129,7 +140,7 @@
central-element)
(rule "h1"
:font-size :2em)
(rule "#preview-start-line"
(rule ".dashed-line"
:border-bottom [:1px :dashed foreground-halftone]
:margin-bottom :5em)
(rule "h1, h2, h3, h4"

90
src/NoteHub/views/pages.clj

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
(ns NoteHub.views.pages
(:require [NoteHub.crossover.lib :as lib])
(:require [NoteHub.crossover.lib :as lib]
[clojure.contrib.string :as ccs])
(:use
[NoteHub.storage]
[NoteHub.settings]
@ -34,23 +35,18 @@ @@ -34,23 +35,18 @@
(layout params title [:article (md-to-html md-text)]))
(status 404 (get-page 404))))
; Template for the error sites
(defn page-setter [code message]
; Sets a custom message for each corresponding HTTP status
(doseq [code [400 404 500]]
(set-page! code
(layout message
[:article
[:h1 message]])))
; Sets a message for each corresponding HTTP status
(page-setter 404 "Nothing Found.")
(page-setter 400 "Bad request.")
(page-setter 500 "OMG, Server Exploded.")
(let [message (get-message (keyword (str "status-" code)))]
(layout message
[:article [:h1 message]]))))
; Routes
; ======
; This function answers to a AJAX request: it gets a sesion key and markdown text.
; IT return html version of the provided markdown and a new session key
; It returns the html code of the provided markdown and a new session key.
(defremote get-preview-md [session-key md]
(when (flash-get session-key)
{:session-key (get-flash-key)
@ -58,58 +54,38 @@ @@ -58,58 +54,38 @@
; Landing Page
(defpage "/" {}
(layout "Free Markdown Hosting"
(layout (get-message :title)
[:div#hero
[:h1 "NoteHub"]
[:h2 "Free and hassle-free hosting for markdown pages."]
[:h1 (get-message :name)]
[:h2 (get-message :title)]
[:br]
[:a.landing-button {:href "/new"} "New Page"]]
[:div#preview-start-line]
[:table.central-element.helvetica-neue
[:tr
[:td.one-third-column
[:h2 "Why?"]
"Not every person, who occasionally wants to express some thoughts, needs a blog.
Blogs are <b>tedious</b> for writers and for readers. Most people are not interested in thoughts
of other random people. Moreover, nowadays everything rotates around social networks and not
individual blogs. It makes much more sense to publish something somewhere and to share
the link with the audience on the community or social network of your choice, than to maintain a blog
trying to keep your readers interested.
<b>NoteHub</b> should be the place, where you can publish your thoughts without hassle."]
[:td.one-third-column
[:h2 "How to Use?"]
"First create a new page using the markdown syntax. Now, besides just sharing the link, you can
view some rudimentary statistics by appending <code>/stats</code> to the note url:
<pre>notehub.org/.../title/stats</pre>
If you want to export a note in the original Markdown format, append <code>/export</code>
<pre>notehub.org/.../title/export</pre>
And if you want, you also can invert the color scheme by appending <code>?theme=dark</code> to the note url.
<pre>notehub.org/.../title?theme=dark</pre>"]
[:td.one-third-column
[:h2 "For Geeks!"]
"NoteHub was an experiment and is implemented entirely in Clojure and ClojureScript. Its source code can
be found on GitHub. Look at the code to find some undocumented NoteHub features (or bugs) and &mdash; feel free to contribute!
(If you are interested in more detailed code overview, read the following note.) NoteHub's design
is intentionally kept extremelly simple and minimalistic, and should stay like this.
NoteHub's persistence layer bases on the key-value store redis.
Currently, NoteHub is hosted for free on Heroku.
Send your feedback and comments directly to @chmllr."]]]))
[:a.landing-button {:href "/new" :style "color: white"} (get-message :new-page)]]
[:div.dashed-line]
[:table.central-element.helvetica-neue
[:tr
[:td.one-third-column
[:h2 (get-message :column-why)] (md-to-html (get-message :column-why-long))]
[:td.one-third-column
[:h2 (get-message :column-how)] (md-to-html (get-message :column-how-long))]
[:td.one-third-column
[:h2 (get-message :column-geeks)] (md-to-html (get-message :column-geeks-long))]]]
[:div.centered.helvetica-neue (md-to-html (get-message :created-by))]))
; New Note Page
(defpage "/new" {}
(layout {:js true} "New Markdown Note"
(layout {:js true} (get-message :new-note)
[:div.central-element
(form-to [:post "/post-note"]
(hidden-field :session-key (get-flash-key))
(hidden-field {:id :session-value} :session-value)
(text-area {:class :max-width} :draft "Loading...")
(text-area {:class :max-width} :draft (get-message :loading))
[:div#buttons.hidden
(submit-button {:style "float: left"
:class :button
:id :publish-button} "Publish")
:id :publish-button} (get-message :publish))
[:button#preview-button.button {:type :button
:style "float: right"} "Preview"]])]
[:div#preview-start-line.hidden]
:style "float: right"} (get-message :preview)]])]
[:div#preview-start-line.dashed-line.hidden]
[:article#preview]))
; Display the note
@ -127,14 +103,14 @@ @@ -127,14 +103,14 @@
(defpage "/:year/:month/:day/:title/stat" {:keys [year month day title]}
(let [views (get-views [year month day] title)]
(if views
(layout "Statistics"
(layout (get-message :statistics)
[:article.helvetica-neue
[:table {:style "width: 100%"}
[:tr
[:td "Published"]
[:td (get-message :published)]
[:td (interpose "-" [year month day])]]
[:tr
[:td "Article views"]
[:td (get-message :article-views)]
[:td views]]]])
(status 404 (get-page 404)))))
@ -151,11 +127,11 @@ @@ -151,11 +127,11 @@
(let [[year month day] (map #(+ (second %) (.get (Calendar/getInstance) (first %)))
{Calendar/YEAR 0, Calendar/MONTH 1, Calendar/DAY_OF_MONTH 0})
untrimmed-line (filter #(or (= \- %) (Character/isLetterOrDigit %))
(-> draft (split #"\n") first (sreplace " " "-") lower-case))
(-> draft ccs/split-lines first (sreplace " " "-") lower-case))
trim (fn [s] (apply str (drop-while #(= \- %) s)))
title-uncut (-> untrimmed-line trim reverse trim reverse)
proposed-title (apply str (take (get-setting :max-title-length #(Integer/parseInt %) 80)
title-uncut))
max-length (get-setting :max-title-length #(Integer/parseInt %) 80)
proposed-title (apply str (take max-length title-uncut))
date [year month day]
title (first (drop-while #(note-exists? date %)
(cons proposed-title

Loading…
Cancel
Save