Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

initial import

  • Loading branch information...
commit a58e71c1e55d9ab2be8c9d462b5eaaf887e0dc6b 0 parents
@madx authored
5 config.ru
@@ -0,0 +1,5 @@
+require File.join(File.dirname(__FILE__), 'lib', 'haze')
+
+Haze.reload!
+
+run Haze::App
25 lib/haze.rb
@@ -0,0 +1,25 @@
+require 'time'
+require 'pathname'
+require 'sinatra/base'
+require 'haml'
+require 'mime/types'
+
+module Haze
+ extend self
+
+ attr_reader :posts, :tags
+
+ @posts, @tags = [], {}
+
+ def reload!
+ @posts = Dir['entries/*'].map {|p| Post.open(p) }.sort_by {|p| p.date }
+ @posts.map {|p| p.tags }.flatten.tap do |ts|
+ @tags = ts.flatten.uniq.inject({}) {|h,t| h.merge({t => ts.count(t)}) }
+ end
+ end
+
+end
+
+%w(post app).each {|l|
+ require File.join(File.dirname(__FILE__), 'haze', l)
+}
44 lib/haze/app.rb
@@ -0,0 +1,44 @@
+module Haze
+ class App < Sinatra::Base
+ configure do
+ set :haml, :attr_wrapper => '"'
+ end
+
+ get '/' do
+ @entry = Haze.posts.last
+ raise Sinatra::NotFound unless @entry
+
+ haml :entry
+ end
+ # Fix to allow mapping to an url with Rack
+ get('') { redirect env['SCRIPT_NAME']+'/' }
+
+ get '/contents' do
+ @entries = Haze.posts.reverse
+
+ if params[:tag]
+ @entries = @entries.select {|p| p.tags.include?(params[:tag]) }
+ end
+
+ haml :contents
+ end
+
+ get '/pub/*' do
+ path = File.join('public', params[:splat].first)
+ halt 403 if path.include?('..')
+
+ content_type MIME::Types.of(path).first.to_s
+ File.read path
+ end
+
+ get '/feed' do
+ end
+
+ get '/entry/:slug' do
+ @entry = Haze.posts.detect {|p| p.slug == params[:slug] }
+ raise Sinatra::NotFound unless @entry
+
+ haml :entry
+ end
+ end
+end
37 lib/haze/post.rb
@@ -0,0 +1,37 @@
+module Haze
+ class Post
+ attr_accessor :date, :slug, :title, :body, :tags
+
+ def after
+ Haze.posts[Haze.posts.index(self)+1]
+ end
+
+ def before
+ (idx = Haze.posts.index(self) - 1) < 0 ? nil : Haze.posts[idx]
+ end
+
+ class << self
+ def open(path)
+ path = Pathname.new(path)
+ new.tap {|p|
+ get_attributes(path).map {|a,v| p.__send__(a, v) }
+ }
+ end
+
+ private
+ def get_attributes(path)
+ Hash.new.tap do |a|
+ header, body = path.read.split(/^---+$/, 2)
+ date, a[:slug=] = path.basename.to_s.split('_', 2)
+ base, increment = date.split('+')
+ a[:date=] = Time.parse(base) + (increment || 0).to_i
+ a[:title=] = header.gsub(/\{#.+\}/, '').gsub(/#(\w+)/, '\1').strip
+ a[:tags=] = header.scan(/#(\w+)/).flatten.map {|t| t.downcase }.uniq
+ a[:body=] = body.lstrip
+ end
+ end
+
+ private :new
+ end
+ end
+end
148 public/style.css
@@ -0,0 +1,148 @@
+body {
+ width: 60%;
+ min-width: 600px;
+ margin: 1em auto;
+ font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
+}
+
+a:link, a:visited {
+ text-decoration: none;
+ color: #204a87;
+ padding: 0 1px;
+}
+
+a:hover, a:focus, a:active {
+ color: #729fcf;
+}
+
+h1 {
+ padding: 0.25em 0.5em;
+ margin: 1em auto 0;
+ font-size: 3em;
+ font-family: "Warnock Pro", "Goudy Old Style", "Palatino", Georgia, serif;
+ font-style: italic;
+ text-align: center;
+ color: #3465a4;
+ -moz-border-radius: 12px 12px 0 0;
+}
+
+#content {
+ border-top: 1px solid #d3d7cf;
+ border-bottom: 1px solid #d3d7cf;
+ background-color: #eeeeec;
+ position: relative;
+}
+#content #menu {
+ position: absolute;
+ width: 8em;
+ top: 2em;
+ left: -8em;
+ margin: 0;
+ padding: 0;
+}
+#content #menu li {
+ display: block;
+ font-weight: bold;
+ text-align: right;
+ color: white;
+ padding: 0.5em 1em 0.5em 2em;
+ margin: 0 0 4px;
+ background-color: #cc0000;
+ border-right: 2px solid #a40000;
+}
+#content .entry {
+ position: relative;
+}
+#content .entry h2 {
+ margin: 0;
+ padding: 0.5em 2em;
+ font-family: "Warnock Pro", "Goudy Old Style", "Palatino", Georgia, serif;
+ font-style: italic;
+ font-size: 2em;
+}
+#content .entry p.date {
+ position: absolute;
+ top: 1em;
+ right: -2.5em;
+ font-weight: bold;
+ text-align: center;
+ color: white;
+ padding: 0.5em 1em;
+ margin: 0;
+ background-color: #4e9a06;
+ border: 1px solid #8ae234;
+ -moz-border-radius: 16px;
+ -webkit-border-radius: 16px;
+}
+#content .entry p.date .day {
+ font-size: 1.75em;
+ display: block;
+}
+#content .entry p.date .month {
+ font-size: 1.5em;
+ font-family: "Warnock Pro", "Goudy Old Style", "Palatino", Georgia, serif;
+ font-style: italic;
+ font-weight: bold;
+}
+#content .entry .tags {
+ margin: 0;
+ padding: 0;
+ position: absolute;
+ top: 8em;
+ right: -10em;
+ width: 10em;
+ text-align: left;
+}
+#content .entry .tags li {
+ display: block;
+ margin: 0 0 8px;
+}
+#content .entry .tags a:link, #content .entry .tags a:visited {
+ background-color: #204a87;
+ color: #ccf9ff;
+ border-left: 2px solid #0c3673;
+ padding: 2px 6px 2px 4px;
+ text-decoration: none;
+ -moz-border-radius: 0 5px 5px 0;
+ -webkit-border-radius: 0 5px 5px 0;
+}
+#content .entry .tags a:hover, #content .entry .tags a:focus, #content .entry .tags a:active {
+ background-color: #3465a4;
+ border-color: #205190;
+}
+#content .entry .body {
+ margin: 0 4em 1em 2em;
+ padding: 0.25em 1.25em;
+ background-color: #fdfdfb;
+ border-top: 1px solid #d3d7cf;
+ font-size: 1.15em;
+ line-height: 160%;
+ color: #555753;
+}
+#content .entry .body h3 {
+ margin: 1em 0 0;
+}
+#content .entry .body pre {
+ background-color: #000023;
+ color: #d3d7cf;
+ font-family: Monaco, "DejaVu Sans Mono", monospace;
+ font-size: 0.9em;
+ padding: 0.25em 0.5em;
+ border: 2px solid #204a87;
+ width: 90%;
+ margin: 1em auto;
+}
+#content .entry .body code {
+ background-color: #000023;
+ color: #d3d7cf;
+ font-family: Monaco, "DejaVu Sans Mono", monospace;
+ padding: 1px 4px;
+ font-size: 0.9em;
+}
+
+#nav {
+ text-align: center;
+ font-size: 1.2em;
+ font-weight: bold;
+ padding: 0.5em 1em;
+}
158 public/style.sass
@@ -0,0 +1,158 @@
+!aluminium_1 = #eeeeec
+!aluminium_2 = #d3d7cf
+!aluminium_3 = #babdb6
+!aluminium_4 = #888a85
+!aluminium_5 = #555753
+!aluminium_6 = #2e3436
+!butter_1 = #fce94f
+!butter_2 = #edd400
+!butter_3 = #c4a000
+!green_1 = #8ae234
+!green_2 = #73d216
+!green_3 = #4e9a06
+!brown_1 = #e9b96e
+!brown_2 = #c17d11
+!brown_3 = #8f5902
+!orange_1 = #fcaf3e
+!orange_2 = #f57900
+!orange_3 = #ce5c00
+!purple_1 = #ad7fa8
+!purple_2 = #75507b
+!purple_3 = #5c3566
+!red_1 = #ef2929
+!red_2 = #cc0000
+!red_3 = #a40000
+!blue_1 = #729fcf
+!blue_2 = #3465a4
+!blue_3 = #204a87
+
+=serif-italics
+ :font-family "Warnock Pro", "Goudy Old Style", "Palatino", Georgia, serif
+ :font-style italic
+
+=code
+ :background-color = !blue_3 - 100
+ :color = !aluminium_2
+ :font-family Monaco, "DejaVu Sans Mono", monospace
+
+body
+ :width 60%
+ :min-width 600px
+ :margin 1em auto
+ :font-family "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif
+
+a:link, a:visited
+ :text-decoration none
+ :color = !blue_3
+ :padding 0 1px
+a:hover, a:focus, a:active
+ :color = !blue_1
+
+h1
+ :padding 0.25em 0.5em
+ :margin 1em auto 0
+ :font-size 3em
+ +serif-italics
+ :text-align center
+ :color = !blue_2
+ :-moz-border-radius 12px 12px 0 0
+
+#content
+ :border-top = 1px solid !aluminium_2
+ :border-bottom = 1px solid !aluminium_2
+ :background-color = !aluminium_1
+ :position relative
+
+ #menu
+ :position absolute
+ :width 8em
+ :top 2em
+ :left -8em
+ :margin 0
+ :padding 0
+ li
+ :display block
+ :font-weight bold
+ :text-align right
+ :color white
+ :padding 0.5em 1em 0.5em 2em
+ :margin 0 0 4px
+ :background-color = !red_2
+ :border-right = 2px solid !red_3
+
+ .entry
+ :position relative
+ h2
+ :margin 0
+ :padding 0.5em 2em
+ +serif-italics
+ :font-size 2em
+ p.date
+ :position absolute
+ :top 1em
+ :right -2.5em
+ :font-weight bold
+ :text-align center
+ :color white
+ :padding 0.5em 1em
+ :margin 0
+ :background-color = !green_3
+ :border = 1px solid !green_1
+ :-moz-border-radius 16px
+ :-webkit-border-radius 16px
+ .day
+ :font-size 1.75em
+ :display block
+ .month
+ :font-size 1.5em
+ +serif-italics
+ :font-weight bold
+ .tags
+ :margin 0
+ :padding 0
+ :position absolute
+ :top 8em
+ :right -10em
+ :width 10em
+ :text-align left
+ li
+ :display block
+ :margin 0 0 8px
+ a:link, a:visited
+ :background-color = !blue_3
+ :color = !blue_1 + 90
+ :border-left = 2px solid !blue_3 - 20
+ :padding 2px 6px 2px 4px
+ :text-decoration none
+ :-moz-border-radius 0 5px 5px 0
+ :-webkit-border-radius 0 5px 5px 0
+ a:hover, a:focus, a:active
+ :background-color = !blue_2
+ :border-color = !blue_2 - 20
+ .body
+ :margin 0 4em 1em 2em
+ :padding 0.25em 1.25em
+ :background-color = !aluminium_1 + 15
+ :border-top = 1px solid !aluminium_2
+ :font-size 1.15em
+ :line-height 160%
+ :color = !aluminium_5
+ h3
+ :margin 1em 0 0
+ pre
+ +code
+ :font-size 0.9em
+ :padding 0.25em 0.5em
+ :border = 2px solid !blue_3
+ :width 90%
+ :margin 1em auto
+ code
+ +code
+ :padding 1px 4px
+ :font-size 0.9em
+
+#nav
+ :text-align center
+ :font-size 1.2em
+ :font-weight bold
+ :padding 0.5em 1em
10 views/contents.haml
@@ -0,0 +1,10 @@
+- if params[:tag]
+ %h2 Entries tagged #{params[:tag]}
+- else
+ %h2 All entries
+%ul#entries
+ - @entries.each do |entry|
+ %li.description
+ %span.date= entry.date.strftime('%F')
+ %a{:href => "/entry/#{entry.slug}"}= entry.title
+ %span.tags= entry.tags.join(', ')
20 views/entry.haml
@@ -0,0 +1,20 @@
+.entry
+ %h2= @entry.title
+ %p.date
+ %span.day= @entry.date.strftime "%d"
+ %span.month= @entry.date.strftime "%b"
+ %ul.tags
+ - @entry.tags.each do |tag|
+ %li
+ %a{:href => "/contents?tag=#{tag}",
+ :title => "Entries tagged #{tag}"}= tag
+ .body= @entry.body
+
+#nav
+ - if _ = @entry.before
+ %span#go-before
+ %a{:href => "/entry/#{_.slug}", :title => "Previous entry"} «
+ %span#go-current= Haze.posts.index(@entry)
+ - if _ = @entry.after
+ %span#go-after
+ %a{:href => "/entry/#{_.slug}", :title => "Next entry"} »
14 views/layout.haml
@@ -0,0 +1,14 @@
+!!! Strict
+%html{'xml:lang' => 'en', :xmlns => "http://www.w3.org/1999/xhtml"}
+ %head
+ %title Haze
+ %meta{'http-equiv' => 'Content-Type', :content => 'text/html;charset=utf-8'}
+ %link{:rel => "stylesheet", :href => "/pub/style.css",
+ :media => "screen", :type => "text/css"}
+ %body
+ %h1 Haze
+ #content
+ = yield
+ %p#footer
+ %a{:href => '/contents'} Browse contents
+ \| powered by <em>Haze</em>

0 comments on commit a58e71c

Please sign in to comment.
Something went wrong with that request. Please try again.