diff options
69 files changed, 1690 insertions, 618 deletions
@@ -1,8 +1,8 @@ .bundle .DS_Store .sass-cache -_gist_cache -_code_cache +.gist-cache +.pygments-cache _deploy public sass.old @@ -10,3 +10,4 @@ source.old source/_stash source/stylesheets/screen.css vendor +node_modules diff --git a/.rbenv-version b/.rbenv-version new file mode 100644 index 00000000..0a95b9f5 --- /dev/null +++ b/.rbenv-version @@ -0,0 +1 @@ +1.9.2-p290 @@ -1 +1 @@ -rvm 1.9.2 +rvm use 1.9.2 diff --git a/.slugignore b/.slugignore new file mode 100644 index 00000000..0a41d013 --- /dev/null +++ b/.slugignore @@ -0,0 +1,3 @@ +plugins +sass +source diff --git a/.themes/classic/sass/base/_layout.scss b/.themes/classic/sass/base/_layout.scss index 4a3c780f..81903428 100644 --- a/.themes/classic/sass/base/_layout.scss +++ b/.themes/classic/sass/base/_layout.scss @@ -14,6 +14,10 @@ $sidebar-width-wide: 300px !default; $indented-lists: false !default; +$header-font-size: 1em !default; +$header-padding-top: 1.5em !default; +$header-padding-bottom: 1.5em !default; + .group { @include pie-clearfix; } @mixin collapse-sidebar { @@ -32,7 +36,10 @@ $indented-lists: false !default; &.thirds section { width: 30%; margin-left: 5%; - &.first { margin-left: 0; } + &.first { + margin-left: 0; + clear: both; + } } } @@ -41,7 +48,7 @@ body { max-width: $max-width; position: relative; margin: 0 auto; - > header, > nav, > footer, #content > article, #content > div > article, #content > div > section, nav[role=pagination] { + > header, > nav, > footer, #content > article, #content > div > article, #content > div > section { @extend .group; padding-left: $pad-min; padding-right: $pad-min; @@ -58,16 +65,36 @@ body { padding-right: $pad-wide; } } + div.pagination { + @extend .group; + margin-left: $pad-min; + margin-right: $pad-min; + @media only screen and (min-width: 480px) { + margin-left: $pad-narrow; + margin-right: $pad-narrow; + } + @media only screen and (min-width: 768px) { + margin-left: $pad-medium; + margin-right: $pad-medium; + } + @media only screen and (min-width: 992px) { + margin-left: $pad-wide; + margin-right: $pad-wide; + } + } > header { - font-size: 1em; - padding-top: 1.5em; - padding-bottom: 1.5em; + font-size: $header-font-size; + padding-top: $header-padding-top; + padding-bottom: $header-padding-bottom; } } -#content { > div, > article { width: 100%; }} +#content { + overflow: hidden; + > div, > article { width: 100%; } +} -aside[role=sidebar] { +aside.sidebar { float: none; padding: 0 $pad-min 1px; background-color: lighten($sidebar-bg, 2); @@ -88,28 +115,30 @@ aside[role=sidebar] { body.sidebar-footer { @media only screen and (min-width: 750px) { - aside[role=sidebar]{ @include collapse-sidebar; } + aside.sidebar{ @include collapse-sidebar; } } #content { margin-right: 0px; } .toggle-sidebar { display: none; } } @media only screen and (min-width: 550px) { - body > header { font-size: 1em; } + body > header { font-size: $header-font-size; } } @media only screen and (min-width: 750px) { - aside[role=sidebar] { @include collapse-sidebar; } + aside.sidebar { @include collapse-sidebar; } +} +#main, #content, .sidebar { + @extend .group; } @media only screen and (min-width: 768px) { body { -webkit-text-size-adjust: auto; } - body > header { font-size: 1.2em; } + body > header { font-size: $header-font-size * 1.2; } #main { - @extend .group; padding: 0; margin: 0 auto; } #content { - @extend .group; + overflow: visible; margin-right: $sidebar-width-medium; position: relative; .no-sidebar & { margin-right: 0; border-right: 0; } @@ -120,8 +149,7 @@ body.sidebar-footer { float: left; } } - aside[role=sidebar] { - @extend .group; + aside.sidebar { width: $sidebar-width-medium - $sidebar-pad-medium*2; padding: 0 $sidebar-pad-medium $sidebar-pad-medium; background: none; @@ -139,7 +167,7 @@ body.sidebar-footer { } @media only screen and (min-width: 992px) { - body > header { font-size: 1.3em; } + body > header { font-size: $header-font-size * 1.3; } #content { margin-right: $sidebar-width-wide; } #content { > div, > article { @@ -147,12 +175,11 @@ body.sidebar-footer { padding-bottom: $pad-wide/2; } } - aside[role=sidebar] { + aside.sidebar { width: $sidebar-width-wide - $sidebar-pad-wide*2; padding: 1.2em $sidebar-pad-wide $sidebar-pad-wide; .collapse-sidebar & { padding: { left: $pad-wide; right: $pad-wide; } - @extend .group; } } } @@ -162,3 +189,4 @@ body.sidebar-footer { ul, ol { margin-left: 0; } } } + diff --git a/.themes/classic/sass/base/_solarized.scss b/.themes/classic/sass/base/_solarized.scss index 30cceb8c..45d8fc5e 100644 --- a/.themes/classic/sass/base/_solarized.scss +++ b/.themes/classic/sass/base/_solarized.scss @@ -18,17 +18,29 @@ $solar-green: #859900 !default; $solarized: dark !default; @if $solarized == light { - $base03: #fdf6e3; - $base02: #eee8d5; - $base01: #93a1a1; - $base00: #839496; - $base0: #657b83; - $base1: #586e75; - $base2: #073642; - $base3: #002b36; + + $_base03: $base03; + $_base02: $base02; + $_base01: $base01; + $_base00: $base00; + $_base0: $base0; + $_base1: $base1; + $_base2: $base2; + $_base3: $base3; + + $base03: $_base3; + $base02: $_base2; + $base01: $_base1; + $base00: $_base0; + $base0: $_base00; + $base1: $_base01; + $base2: $_base02; + $base3: $_base03; } /* non highlighted code colors */ $pre-bg: $base03 !default; -$pre-border: $base02 !default; +$pre-border: darken($base02, 5) !default; $pre-color: $base1 !default; + + diff --git a/.themes/classic/sass/base/_theme.scss b/.themes/classic/sass/base/_theme.scss index fce47e53..9a50a8b4 100644 --- a/.themes/classic/sass/base/_theme.scss +++ b/.themes/classic/sass/base/_theme.scss @@ -1,4 +1,4 @@ -$noise-bg: image-url('noise.png') top left; +$noise-bg: image-url('noise.png') top left !default; $img-border: inline-image('dotted-border.png'); // Main Link Colors @@ -23,6 +23,8 @@ $type-border: #ddd !default; /* Navigation */ $nav-bg: #ccc !default; +$nav-bg-front: image-url('noise.png') !default; +$nav-bg-back: linear-gradient(lighten($nav-bg, 8), $nav-bg, darken($nav-bg, 11)) !default; $nav-color: darken($nav-bg, 38) !default; $nav-color-hover: darken($nav-color, 25) !default; $nav-placeholder: desaturate(darken($nav-bg, 10), 15) !default; @@ -39,13 +41,15 @@ $sidebar-link-color-hover: $link-color-hover !default; $sidebar-link-color-active: $link-color-active !default; $sidebar-color: change-color(mix($text-color, $sidebar-bg, 80), $hue: hue($sidebar-bg), $saturation: saturation($sidebar-bg)/2) !default; $sidebar-border: desaturate(darken($sidebar-bg, 7), 10) !default; -$sidebar-border: darken($sidebar-bg, 7) !default; +$sidebar-border-hover: darken($sidebar-bg, 7) !default; $sidebar-link-color-subdued: lighten($sidebar-color, 20) !default; $sidebar-link-color-subdued-hover: $sidebar-link-color-hover !default; $twitter-status-link: lighten($sidebar-link-color-subdued, 15) !default; $footer-color: #888 !default; $footer-bg: #ccc !default; +$footer-bg-front: image-url('noise.png') !default; +$footer-bg-back: linear-gradient(lighten($footer-bg, 8), $footer-bg, darken($footer-bg, 11)) !default; $footer-color: darken($footer-bg, 38) !default; $footer-color-hover: darken($footer-color, 10) !default; $footer-border-top: lighten($footer-bg, 15) !default; @@ -60,7 +64,7 @@ $page-border-bottom: darken($footer-bg, 5) !default; a { @include link-colors($link-color, $hover: $link-color-hover, $focus: $link-color-hover, $visited: $link-color-visited, $active: $link-color-active); } -aside[role=sidebar] a { +aside.sidebar a { @include link-colors($sidebar-link-color, $hover: $sidebar-link-color-hover, $focus: $sidebar-link-color-hover, $active: $sidebar-link-color-active); } a { diff --git a/.themes/classic/sass/base/_typography.scss b/.themes/classic/sass/base/_typography.scss index ef83065b..b68753fa 100644 --- a/.themes/classic/sass/base/_typography.scss +++ b/.themes/classic/sass/base/_typography.scss @@ -1,21 +1,30 @@ $blockquote: $type-border !default; -$mono: Menlo, Monaco, "Andale Mono", "lucida console", "Courier New", monospace; +$sans: "PT Sans", "Helvetica Neue", Arial, sans-serif !default; +$serif: "PT Serif", Georgia, Times, "Times New Roman", serif !default; +$mono: Menlo, Monaco, "Andale Mono", "lucida console", "Courier New", monospace !default; +$heading-font-family: "PT Serif", "Georgia", "Helvetica Neue", Arial, sans-serif !default; +$header-title-font-family: $heading-font-family !default; +$header-subtitle-font-family: $heading-font-family !default; // Fonts .heading { - font-family: "PT Serif", "Georgia", "Helvetica Neue", Arial, sans-serif; + font-family: $heading-font-family; } -.sans { font-family: "PT Sans", "Helvetica Neue", Arial, sans-serif; } -.serif { font-family: "PT Serif", Georgia, Times, "Times New Roman", serif; } +.sans { font-family: $sans; } +.serif { font-family: $serif; } .mono { font-family: $mono; } body > header h1 { font-size: 2.2em; @extend .heading; + font-family: $header-title-font-family; font-weight: normal; line-height: 1.2em; margin-bottom: 0.6667em; } +body > header h2 { + font-family: $header-subtitle-font-family; +} body { line-height: 1.5em; @@ -56,12 +65,12 @@ h6, section h5, section section h4, section section section h3 { p, blockquote, ul, ol { margin-bottom: 1.5em; } ul { list-style-type: disc; - ul { list-style-type: circle; - ul { list-style-type: square; }}} + ul { list-style-type: circle; margin-bottom: 0px; + ul { list-style-type: square; margin-bottom: 0px; }}} ol { list-style-type: decimal; - ol { list-style-type: lower-alpha; - ol { list-style-type: lower-roman; }}} + ol { list-style-type: lower-alpha; margin-bottom: 0px; + ol { list-style-type: lower-roman; margin-bottom: 0px; }}} ul, ol { &, ul, ol { margin-left: 1.3em; }} @@ -115,7 +124,8 @@ blockquote { } } -.has-pullquote:before { +.pullquote-right:before, +.pullquote-left:before { /* Reset metrics. */ padding: 0; border: none; @@ -134,6 +144,13 @@ blockquote { font-size: 1.4em; line-height: 1.45em; } + +.pullquote-left:before { + /* Make left pullquotes align properly. */ + float: left; + margin: .5em 1.5em 1em 0; +} + /* @extend this to force long lines of continuous text to wrap */ .force-wrap { white-space: -moz-pre-wrap; diff --git a/.themes/classic/sass/custom/_colors.scss b/.themes/classic/sass/custom/_colors.scss index 9a344045..740266a8 100644 --- a/.themes/classic/sass/custom/_colors.scss +++ b/.themes/classic/sass/custom/_colors.scss @@ -5,13 +5,18 @@ //$header-bg: #263347; //$subtitle-color: lighten($header-bg, 58); //$nav-bg: desaturate(lighten(#8fc17a, 18), 5); +//$nav-bg-front: image-url('noise.png'); +//$nav-bg-back: linear-gradient(lighten($nav-bg, 8), $nav-bg, darken($nav-bg, 11)); //$sidebar-bg: desaturate(#eceff5, 8); //$sidebar-link-color: saturate(#526f9a, 10); //$sidebar-link-color-hover: darken(#7ab662, 9); +//$footer-bg: #ccc !default; +//$footer-bg-front: image-url('noise.png'); +//$footer-bg-back: linear-gradient(lighten($footer-bg, 8), $footer-bg, darken($footer-bg, 11)); /* To use the light Solarized highlighting theme uncomment the following line */ -//$solarized: light +//$solarized: light; /* If you want to tweak the Solarized colors you can do that here */ //$base03: #002b36; //darkest blue @@ -34,5 +39,5 @@ /* Non highlighted code colors */ //$pre-bg: $base03; -//$pre-border: $base02; +//$pre-border: darken($base02, 5); //$pre-color: $base1; diff --git a/.themes/classic/sass/custom/_fonts.scss b/.themes/classic/sass/custom/_fonts.scss new file mode 100644 index 00000000..1a6b2a06 --- /dev/null +++ b/.themes/classic/sass/custom/_fonts.scss @@ -0,0 +1,10 @@ +// Here you can easily change font faces which are used in your site. +// To give it a try, uncomment some of the lines below rebuild your blog, and see how it works. your sites's. +// If you love to use Web Fonts, you also need to add some lines to source/_includes/custom/head.html + +//$sans: "Optima", sans-serif; +//$serif: "Baskerville", serif; +//$mono: "Courier", monospace; +//$heading-font-family: "Verdana", sans-serif; +//$header-title-font-family: "Futura", sans-serif; +//$header-subtitle-font-family: "Futura", sans-serif; diff --git a/.themes/classic/sass/custom/_layout.scss b/.themes/classic/sass/custom/_layout.scss index 53173115..74c7de9d 100644 --- a/.themes/classic/sass/custom/_layout.scss +++ b/.themes/classic/sass/custom/_layout.scss @@ -1,6 +1,10 @@ // Here you can easily change your sites's layout. // To give it a try, uncomment some of the lines below, make changes, rebuild your blog, and see how it works. +//$header-font-size: 1em; +//$header-padding-top: 1.5em; +//$header-padding-bottom: 1.5em; + //$max-width: 1350px; //$indented-lists: true; diff --git a/.themes/classic/sass/partials/_blog.scss b/.themes/classic/sass/partials/_blog.scss index 558f0a22..57fe7a8a 100644 --- a/.themes/classic/sass/partials/_blog.scss +++ b/.themes/classic/sass/partials/_blog.scss @@ -1,5 +1,4 @@ article { - overflow: hidden; padding-top: 1em; a { @extend .force-wrap; } header { @@ -74,6 +73,8 @@ article { p.meta { margin-bottom: .8em; font-size: .85em; + clear: both; + overflow: hidden; } .byline + time:before, time +time:before, .comments:before, .byline ~ .categories:before { @extend .separator; @@ -121,14 +122,12 @@ article + article { display: inline-block; } -#content nav[role=pagination] { +#content div.pagination { text-align: center; font-size: .95em; - div { - position: relative; - background: $img-border top left repeat-x; - padding: {top: 1.5em; bottom: 1.5em;} - } + position: relative; + background: $img-border top left repeat-x; + padding: {top: 1.5em; bottom: 1.5em;} a { text-decoration: none; color: $text-color-light; diff --git a/.themes/classic/sass/partials/_footer.scss b/.themes/classic/sass/partials/_footer.scss index e750342c..37411225 100644 --- a/.themes/classic/sass/partials/_footer.scss +++ b/.themes/classic/sass/partials/_footer.scss @@ -4,7 +4,7 @@ body > footer { color: $footer-color; text-shadow: lighten($footer-bg, 5) 0 1px; background-color: $footer-bg; - @include background(image-url('noise.png'), linear-gradient(lighten($footer-bg, 8), $footer-bg, darken($footer-bg, 11))); + @include background($footer-bg-front, $footer-bg-back); border-top: 1px solid $footer-border-top; position: relative; padding-top: 1em; diff --git a/.themes/classic/sass/partials/_navigation.scss b/.themes/classic/sass/partials/_navigation.scss index 7af9f9f7..30fa011d 100644 --- a/.themes/classic/sass/partials/_navigation.scss +++ b/.themes/classic/sass/partials/_navigation.scss @@ -1,7 +1,7 @@ body > nav { position: relative; background-color: $nav-bg; - @include background(image-url('noise.png'), linear-gradient(lighten($nav-bg, 8), $nav-bg, darken($nav-bg, 11))); + @include background($nav-bg-front, $nav-bg-back); border: { top: 1px solid $nav-border-top; bottom: 1px solid $nav-border-bottom; } @@ -13,7 +13,7 @@ body > nav { .search { padding: .3em .5em 0; font-size: .85em; - @extend .sans; + font-family: $sans; line-height: 1.1em; width: 95%; @include border-radius(.5em); @@ -31,8 +31,8 @@ body > nav { } } } - fieldset[role=site-search]{ float: right; width: 48%; } - fieldset[role=mobile-nav]{ float: left; width: 48%; + fieldset[role=search]{ float: right; width: 48%; } + fieldset.mobile-nav{ float: left; width: 48%; select{ width: 100%; font-size: .8em; border: 1px solid #888;} } ul { display: none; } @@ -44,7 +44,7 @@ body > nav { display: block; padding-top: .15em; } - ul[role=subscription] { + ul.subscription { margin-left: .8em; float: right; li:last-child a { padding-right: 0; } @@ -54,7 +54,7 @@ body > nav { } a { @include link-colors($nav-color, $nav-color-hover, $visited: $nav-color); - @extend .sans; + font-family: $sans; text-shadow: lighten($nav-bg, 12) 0 1px; float: left; text-decoration: none; @@ -85,8 +85,8 @@ body > nav { width: $sidebar-width-medium - $pad-medium*2 - $sidebar-pad-medium - 58px; .search { width: 91%; } } - fieldset[role=mobile-nav] { display: none; } - fieldset[role=site-search]{ width: 99%; } + fieldset.mobile-nav { display: none; } + fieldset[role=search]{ width: 99%; } } @media only screen and (min-width: 992px) { form { @@ -130,7 +130,8 @@ body > nav { } } } - ul[role=subscription] { position: relative; top: .2em; li, a { border: 0; padding: 0; }} + ul.subscription { position: relative; top: .2em; li, a { border: 0; padding: 0; }} a[rel=subscribe-rss]{ @include mask-subscription-nav('rss.png'); } a[rel=subscribe-email]{ @include mask-subscription-nav('email.png'); } } + diff --git a/.themes/classic/sass/partials/_sharing.scss b/.themes/classic/sass/partials/_sharing.scss index 1fa97750..3eecb488 100644 --- a/.themes/classic/sass/partials/_sharing.scss +++ b/.themes/classic/sass/partials/_sharing.scss @@ -4,3 +4,5 @@ background: $img-border top left repeat-x; } } + +#fb-root { display: none; } diff --git a/.themes/classic/sass/partials/_sidebar.scss b/.themes/classic/sass/partials/_sidebar.scss index ac790e04..eec540ba 100644 --- a/.themes/classic/sass/partials/_sidebar.scss +++ b/.themes/classic/sass/partials/_sidebar.scss @@ -1,4 +1,5 @@ @import "sidebar/base"; @import "sidebar/twitter"; +@import "sidebar/googleplus"; @import "sidebar/pinboard"; @import "sidebar/delicious"; diff --git a/.themes/classic/sass/partials/_syntax.scss b/.themes/classic/sass/partials/_syntax.scss index 25e8d329..77ac8d78 100644 --- a/.themes/classic/sass/partials/_syntax.scss +++ b/.themes/classic/sass/partials/_syntax.scss @@ -1,4 +1,5 @@ .highlight, html .gist .gist-file .gist-syntax .gist-highlight { + table td.code { width: 100%; } .line-numbers { text-align: right; font-size: 13px; @@ -20,17 +21,19 @@ } border: 1px solid $pre-border !important; } +figure.code, .gist-file, pre { + @include box-shadow(rgba(#000, .06) 0 0 10px); + .highlight pre { @include box-shadow(none); } +} + html .gist .gist-file { margin-bottom: 1.8em; position: relative; border: none; padding-top: image-height("code_bg.png") !important; .gist-syntax { - @if $solarized == dark { - border-bottom: 1px solid $base03 !important; - } @else if $solarized == light { - border-bottom: 0px; - } + border-bottom: 0 !important; + background: none !important; .gist-highlight{ background: $base03 !important; pre { @@ -45,6 +48,7 @@ html .gist .gist-file { font-size: .7em !important; @if $solarized == light { background: lighten($base03, 2) $noise-bg; + border: 1px solid $pre-border !important; border-top: 1px solid lighten($base03, 2) !important; } @else { background: $base02 $noise-bg; @@ -85,19 +89,21 @@ h3.filename { + pre { @include border-top-radius(0px); } } -p code, -li code { - @extend .mono; - display: inline-block; - white-space: no-wrap; - background: #fff; - font-size: .8em; - line-height: 1.5em; - color: #555; - border: 1px solid #ddd; - @include border-radius(.4em); - padding: 0 .3em; - margin: -1px 0; +p, li { + code { + @extend .mono; + display: inline-block; + white-space: no-wrap; + background: #fff; + font-size: .8em; + line-height: 1.5em; + color: #555; + border: 1px solid #ddd; + @include border-radius(.4em); + padding: 0 .3em; + margin: -1px 0; + } + pre code { font-size: 1em !important; background: none; border: none; } } .pre-code { @@ -201,7 +207,7 @@ pre, .highlight, .gist-highlight { } .highlight code { @extend .pre-code; background: #000;} -figure[role=code] { +figure.code { background: none; padding: 0; border: 0; @@ -216,6 +222,7 @@ figure[role=code] { margin-bottom: 0; } } + .code-title { text-align: center; font-size: 13px; @@ -243,3 +250,4 @@ figure[role=code] { text-shadow: #cbcccc 0 1px 0; padding-left: 3em; } + diff --git a/.themes/classic/sass/partials/sidebar/_base.scss b/.themes/classic/sass/partials/sidebar/_base.scss index a0d1c09e..5441304e 100644 --- a/.themes/classic/sass/partials/sidebar/_base.scss +++ b/.themes/classic/sass/partials/sidebar/_base.scss @@ -1,7 +1,8 @@ .side-shadow-border { @include box-shadow(lighten($sidebar-bg, 5) 0 1px); } -aside[role=sidebar] { +aside.sidebar { + overflow: hidden; color: $sidebar-color; text-shadow: lighten($sidebar-bg, 8) 0 1px; a { @extend .force-wrap; } diff --git a/.themes/classic/sass/partials/sidebar/_googleplus.scss b/.themes/classic/sass/partials/sidebar/_googleplus.scss new file mode 100644 index 00000000..c2a693ee --- /dev/null +++ b/.themes/classic/sass/partials/sidebar/_googleplus.scss @@ -0,0 +1,26 @@ +.googleplus { + h1 { + -moz-box-shadow: none !important; + -webkit-box-shadow: none !important; + -o-box-shadow: none !important; + box-shadow: none !important; + border-bottom: 0px none !important; + } + a { + text-decoration: none; + white-space: normal !important; + line-height: 32px; + + img { + float: left; + margin-right: 0.5em; + border: 0 none; + } + } +} + +.googleplus-hidden { + position: absolute; + top: -1000em; + left: -1000em; +} diff --git a/.themes/classic/sass/partials/sidebar/_twitter.scss b/.themes/classic/sass/partials/sidebar/_twitter.scss index ccc9b53d..dfd49b55 100644 --- a/.themes/classic/sass/partials/sidebar/_twitter.scss +++ b/.themes/classic/sass/partials/sidebar/_twitter.scss @@ -13,7 +13,7 @@ position: relative; padding-right: 1em; } - a[href*=status]{ + a[href*=status]:first-child { color: $twitter-status-link; float: right; padding: 0 0 .1em 1em; diff --git a/.themes/classic/sass/screen.scss b/.themes/classic/sass/screen.scss index f08da4c2..1899f608 100644 --- a/.themes/classic/sass/screen.scss +++ b/.themes/classic/sass/screen.scss @@ -3,6 +3,7 @@ @include reset-html5; @import "custom/colors"; +@import "custom/fonts"; @import "custom/layout"; @import "base"; @import "partials"; diff --git a/.themes/classic/source/_includes/after_footer.html b/.themes/classic/source/_includes/after_footer.html new file mode 100644 index 00000000..08b8e340 --- /dev/null +++ b/.themes/classic/source/_includes/after_footer.html @@ -0,0 +1,5 @@ +{% include disqus.html %} +{% include facebook_like.html %} +{% include google_plus_one.html %} +{% include twitter_sharing.html %} +{% include custom/after_footer.html %} diff --git a/.themes/classic/source/_includes/article.html b/.themes/classic/source/_includes/article.html index 5cd6fda1..23f48844 100644 --- a/.themes/classic/source/_includes/article.html +++ b/.themes/classic/source/_includes/article.html @@ -1,12 +1,17 @@ {% unless page.no_header %} <header> {% if index %} - <h1 class="entry-title"><a href="{{ root_url }}{{ post.url }}">{{ post.title | titlecase }}</a></h1> + <h1 class="entry-title"><a href="{{ root_url }}{{ post.url }}">{% if site.titlecase %}{{ post.title | titlecase }}{% else %}{{ post.title }}{% endif %}</a></h1> {% else %} - <h1 class="entry-title">{{ page.title | titlecase }}</h1> + <h1 class="entry-title">{% if site.titlecase %}{{ page.title | titlecase }}{% else %}{{ page.title }}{% endif %}</h1> {% endif %} {% unless page.meta == false %} - <p class="meta">{% include post/date.html %}{{ time }}</p> + <p class="meta"> + {% include post/date.html %}{{ time }} + {% if site.disqus_short_name and page.comments != false and post.comments != false and site.disqus_show_comment_count == true %} + | <a href="{% if index %}{{ root_url }}{{ post.url }}{% endif %}#disqus_thread">Comments</a> + {% endif %} + </p> {% endunless %} </header> {% endunless %} diff --git a/.themes/classic/source/_includes/asides/delicious.html b/.themes/classic/source/_includes/asides/delicious.html index 307a2e94..115cdcbc 100644 --- a/.themes/classic/source/_includes/asides/delicious.html +++ b/.themes/classic/source/_includes/asides/delicious.html @@ -1,7 +1,8 @@ {% if site.delicious_user %} <section> <h1>On Delicious</h1> - <script type="text/javascript" src="http://feeds.delicious.com/v2/js/{{ site.delicious_user }}?title=&count={{ site.delicious_count }}&sort=date&extended"></script> + <div id="delicious"></div> + <script type="text/javascript" src="http://feeds.delicious.com/v2/json/{{ site.delicious_user }}?count={{ site.delicious_count }}&sort=date&callback=renderDeliciousLinks"></script> <p><a href="http://delicious.com/{{ site.delicious_user }}">My Delicious Bookmarks »</a></p> </section> -{% endif %} +{% endif %}
\ No newline at end of file diff --git a/.themes/classic/source/_includes/asides/github.html b/.themes/classic/source/_includes/asides/github.html index 935ccff0..cb267f09 100644 --- a/.themes/classic/source/_includes/asides/github.html +++ b/.themes/classic/source/_includes/asides/github.html @@ -1,11 +1,11 @@ {% if site.github_user %} <section> - <h1>Github Repos</h1> + <h1>GitHub Repos</h1> <ul id="gh_repos"> <li class="loading">Status updating...</li> </ul> {% if site.github_show_profile_link %} - <a href="https://github.com/{{site.github_user}}">@{{site.github_user}}</a> on Github + <a href="https://github.com/{{site.github_user}}">@{{site.github_user}}</a> on GitHub {% endif %} <script type="text/javascript"> $.domReady(function(){ diff --git a/.themes/classic/source/_includes/asides/googleplus.html b/.themes/classic/source/_includes/asides/googleplus.html new file mode 100644 index 00000000..00a0aa85 --- /dev/null +++ b/.themes/classic/source/_includes/asides/googleplus.html @@ -0,0 +1,11 @@ +{% if site.googleplus_user %} +<section class="googleplus{% if site.googleplus_hidden %} googleplus-hidden{% endif %}"> + <h1> + <a href="https://plus.google.com/{{ site.googleplus_user }}?rel=author"> + <img src="http://www.google.com/images/icons/ui/gprofile_button-32.png" width="32" height="32"> + Google+ + </a> + </h1> +</section> +{% endif %} + diff --git a/.themes/classic/source/_includes/asides/twitter.html b/.themes/classic/source/_includes/asides/twitter.html index fe4eda6a..bab5de47 100644 --- a/.themes/classic/source/_includes/asides/twitter.html +++ b/.themes/classic/source/_includes/asides/twitter.html @@ -11,7 +11,7 @@ </script> <script src="{{ root_url }}/javascripts/twitter.js" type="text/javascript"> </script> {% if site.twitter_follow_button %} - <a href="http://twitter.com/{{ site.twitter_user }}" class="twitter-follow-button" data-width="208px" data-show-count="{{ site.twitter_show_follower_count }}">Follow @{{ site.twitter_user }}</a> + <a href="http://twitter.com/{{ site.twitter_user }}" class="twitter-follow-button" data-show-count="{{ site.twitter_show_follower_count }}">Follow @{{ site.twitter_user }}</a> {% else %} <p>Follow <a href="http://twitter.com/{{site.twitter_user}}">@{{ site.twitter_user }}</a></p> {% endif %} diff --git a/.themes/classic/source/_includes/custom/after_footer.html b/.themes/classic/source/_includes/custom/after_footer.html new file mode 100644 index 00000000..bce25dd9 --- /dev/null +++ b/.themes/classic/source/_includes/custom/after_footer.html @@ -0,0 +1,3 @@ +{% comment %} + Add content to be output at the bottom of each page. (You might use this for analytics scripts, for example) +{% endcomment %} diff --git a/.themes/classic/source/_includes/custom/category_feed.xml b/.themes/classic/source/_includes/custom/category_feed.xml new file mode 100644 index 00000000..f47c5536 --- /dev/null +++ b/.themes/classic/source/_includes/custom/category_feed.xml @@ -0,0 +1,27 @@ +--- +layout: nil +--- +<?xml version="1.0" encoding="utf-8"?> +<feed xmlns="http://www.w3.org/2005/Atom"> + + <title><![CDATA[{{ page.title }} | {{ site.title }}]]></title> + <link href="{{ site.url }}/{{ page.feed_url }}" rel="self"/> + <link href="{{ site.url }}/"/> + <updated>{{ site.time | date_to_xmlschema }}</updated> + <id>{{ site.url }}/</id> + <author> + <name><![CDATA[{{ site.author | strip_html }}]]></name> + {% if site.email %}<email><![CDATA[{{ site.email }}]]></email>{% endif %} + </author> + <generator uri="http://octopress.org/">Octopress</generator> + + {% for post in site.categories[page.category] limit: 5 %} + <entry> + <title type="html"><![CDATA[{{ post.title | cdata_escape }}]]></title> + <link href="{{ site.url }}{{ post.url }}"/> + <updated>{{ post.date | date_to_xmlschema }}</updated> + <id>{{ site.url }}{{ post.id }}</id> + <content type="html"><![CDATA[{{ post.content | expand_urls: site.url | markdownify | cdata_escape }}]]></content> + </entry> + {% endfor %} +</feed> diff --git a/.themes/classic/source/_includes/custom/head.html b/.themes/classic/source/_includes/custom/head.html index 15a6d9d7..85879f4a 100644 --- a/.themes/classic/source/_includes/custom/head.html +++ b/.themes/classic/source/_includes/custom/head.html @@ -1,3 +1,3 @@ -<!--Fonts from Google's Web font directory at http://google.com/webfonts --> -<link href='http://fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold,bolditalic' rel='stylesheet' type='text/css'> -<link href='http://fonts.googleapis.com/css?family=PT+Sans:regular,italic,bold,bolditalic' rel='stylesheet' type='text/css'> +<!--Fonts from Google"s Web font directory at http://google.com/webfonts --> +<link href="http://fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css"> +<link href="http://fonts.googleapis.com/css?family=PT+Sans:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css"> diff --git a/.themes/classic/source/_includes/custom/navigation.html b/.themes/classic/source/_includes/custom/navigation.html index 8f091e16..d6bd4246 100644 --- a/.themes/classic/source/_includes/custom/navigation.html +++ b/.themes/classic/source/_includes/custom/navigation.html @@ -1,4 +1,4 @@ -<ul role=main-navigation> +<ul class="main-navigation"> <li><a href="{{ root_url }}/">Blog</a></li> <li><a href="{{ root_url }}/blog/archives">Archives</a></li> </ul> diff --git a/.themes/classic/source/_includes/disqus.html b/.themes/classic/source/_includes/disqus.html new file mode 100644 index 00000000..eb308779 --- /dev/null +++ b/.themes/classic/source/_includes/disqus.html @@ -0,0 +1,21 @@ +{% comment %} Load script if disquss comments are enabled and `page.comments` is either empty (index) or set to true {% endcomment %} +{% if site.disqus_short_name and page.comments != false %} +<script type="text/javascript"> + var disqus_shortname = '{{ site.disqus_short_name }}'; + {% if page.comments == true %} + {% comment %} `page.comments` can be only be set to true on pages/posts, so we embed the comments here. {% endcomment %} + // var disqus_developer = 1; + var disqus_identifier = '{{ site.url }}{{ page.url }}'; + var disqus_url = '{{ site.url }}{{ page.url }}'; + var disqus_script = 'embed.js'; + {% else %} + {% comment %} As `page.comments` is empty, we must be on the index page. {% endcomment %} + var disqus_script = 'count.js'; + {% endif %} + (function () { + var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; + dsq.src = 'http://' + disqus_shortname + '.disqus.com/' + disqus_script; + (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq); + }()); +</script> +{% endif %} diff --git a/.themes/classic/source/_includes/facebook_like.html b/.themes/classic/source/_includes/facebook_like.html new file mode 100644 index 00000000..74f91307 --- /dev/null +++ b/.themes/classic/source/_includes/facebook_like.html @@ -0,0 +1,10 @@ +{% if site.facebook_like %} +<div id="fb-root"></div> +<script>(function(d, s, id) { + var js, fjs = d.getElementsByTagName(s)[0]; + if (d.getElementById(id)) {return;} + js = d.createElement(s); js.id = id; + js.src = "//connect.facebook.net/en_US/all.js#appId=212934732101925&xfbml=1"; + fjs.parentNode.insertBefore(js, fjs); +}(document, 'script', 'facebook-jssdk'));</script> +{% endif %} diff --git a/.themes/classic/source/_includes/head.html b/.themes/classic/source/_includes/head.html index d1741120..d7abd6fd 100644 --- a/.themes/classic/source/_includes/head.html +++ b/.themes/classic/source/_includes/head.html @@ -4,27 +4,26 @@ <!--[if (gt IE 8)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js" lang="en"><!--<![endif]--> <head> <meta charset="utf-8"> - <title>{% if page.title %}{{page.title}} - {% endif %}{{site.title}}</title> - <meta name="author" content="{{site.author}}"> - {% if page.description %} - <meta name="description" content="{{page.description}}"/> - {% endif %} + <title>{% if page.title %}{{ page.title }} - {% endif %}{{ site.title }}</title> + <meta name="author" content="{{ site.author }}"> + + {% capture description %}{% if page.description %}{{ page.description }}{% else %}{{ content | raw_content }}{% endif %}{% endcapture %} + <meta name="description" content="{{ description | strip_html | condense_spaces | truncate:150 }}"> + {% if page.keywords %}<meta name="keywords" content="{{ page.keywords }}">{% endif %} <!-- http://t.co/dKP3o1e --> <meta name="HandheldFriendly" content="True"> <meta name="MobileOptimized" content="320"> <meta name="viewport" content="width=device-width, initial-scale=1"> - {% if page.keywords %} - <meta name="keywords" content="{{page.keywords}}"/> - {% endif %} - - <link rel="canonical" href="{{ site.url }}{{ page.url }}"/> - <link href="{{ root_url }}/favicon.png" rel="shortcut icon" /> + {% capture canonical %}{{ site.url }}{% if site.permalink contains '.html' %}{{ page.url }}{% else %}{{ page.url | remove:'index.html' }}{% endif %}{% endcapture %} + <link rel="canonical" href="{{ canonical }}"> + <link href="{{ root_url }}/favicon.png" rel="icon"> <link href="{{ root_url }}/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css"> <script src="{{ root_url }}/javascripts/modernizr-2.0.js"></script> - <script src="http://s3.amazonaws.com/ender-js/jeesh.min.js"></script> + <script src="{{ root_url }}/javascripts/ender.js"></script> <script src="{{ root_url }}/javascripts/octopress.js" type="text/javascript"></script> - <link href="{{ site.subscribe_rss }}" rel="alternate" title="{{site.title}}" type="application/atom+xml"/> + <link href="{{ site.subscribe_rss }}" rel="alternate" title="{{site.title}}" type="application/atom+xml"> {% include custom/head.html %} + {% include google_analytics.html %} </head> diff --git a/.themes/classic/source/_includes/navigation.html b/.themes/classic/source/_includes/navigation.html index c26908f8..2f0e6280 100644 --- a/.themes/classic/source/_includes/navigation.html +++ b/.themes/classic/source/_includes/navigation.html @@ -1,13 +1,15 @@ -<ul role=subscription data-subscription="rss{% if site.subscribe_email %} email{% endif %}"> +<ul class="subscription" data-subscription="rss{% if site.subscribe_email %} email{% endif %}"> <li><a href="{{ site.subscribe_rss }}" rel="subscribe-rss" title="subscribe via RSS">RSS</a></li> {% if site.subscribe_email %} <li><a href="{{ site.subscribe_email }}" rel="subscribe-email" title="subscribe via email">Email</a></li> {% endif %} </ul> + {% if site.simple_search %} <form action="{{ site.simple_search }}" method="get"> - <fieldset role="site-search"> + <fieldset role="search"> <input type="hidden" name="q" value="site:{{ site.url | shorthand_url }}" /> <input class="search" type="text" name="q" results="0" placeholder="Search"/> </fieldset> </form> + {% endif %} {% include custom/navigation.html %} diff --git a/.themes/classic/source/_includes/post/date.html b/.themes/classic/source/_includes/post/date.html index dbfa67ae..ecf1ad71 100644 --- a/.themes/classic/source/_includes/post/date.html +++ b/.themes/classic/source/_includes/post/date.html @@ -1,12 +1,15 @@ {% capture date %}{{ page.date }}{{ post.date }}{% endcapture %} +{% capture date_formatted %}{{ page.date_formatted }}{{ post.date_formatted }}{% endcapture %} {% capture has_date %}{{ date | size }}{% endcapture %} + {% capture updated %}{{ page.updated }}{{ post.updated }}{% endcapture %} +{% capture updated_formatted %}{{ page.updated_formatted }}{{ post.updated_formatted }}{% endcapture %} {% capture was_updated %}{{ updated | size }}{% endcapture %} {% if has_date != '0' %} - {% capture time %}<time datetime="{{ date | datetime | date_to_xmlschema }}" pubdate {% if updated %} data-updated="true" {% endif %}>{{ date | ordinalize }}</time>{% endcapture %} + {% capture time %}<time datetime="{{ date | datetime | date_to_xmlschema }}" pubdate{% if updated %} data-updated="true"{% endif %}>{{ date_formatted }}</time>{% endcapture %} {% endif %} {% if was_updated != '0' %} - {% capture updated %}<time class="updated" datetime="{{ updated | datetime | date_to_xmlschema }}">Updated {{ updated | ordinalize }}</time>{% endcapture %} -{% else %}{% assign updated = false %}{% endif %} + {% capture updated %}<time datetime="{{ updated | datetime | date_to_xmlschema }}" class="updated">Updated {{ updated_formatted }}</time>{% endcapture %} +{% else %}{% assign updated = false %}{% endif %}
\ No newline at end of file diff --git a/.themes/classic/source/_includes/post/disqus_thread.html b/.themes/classic/source/_includes/post/disqus_thread.html index f966f03a..b1acd8cc 100644 --- a/.themes/classic/source/_includes/post/disqus_thread.html +++ b/.themes/classic/source/_includes/post/disqus_thread.html @@ -1,13 +1 @@ -<div id="disqus_thread"></div> -<script type="text/javascript"> - var disqus_shortname = '{{ site.disqus_short_name }}'; - var disqus_identifier = '{{ site.url }}{{ page.url }}'; - var disqus_url = '{{ site.url }}{{ page.url }}'; - //var disqus_developer = 1; - (function() { - var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; - dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js'; - (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq); - })(); -</script> <noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript> diff --git a/.themes/classic/source/_includes/post/sharing.html b/.themes/classic/source/_includes/post/sharing.html index f0f9b9db..e32500d0 100644 --- a/.themes/classic/source/_includes/post/sharing.html +++ b/.themes/classic/source/_includes/post/sharing.html @@ -5,4 +5,7 @@ {% if site.google_plus_one %} <div class="g-plusone" data-size="{{ site.google_plus_one_size }}"></div> {% endif %} + {% if site.facebook_like %} + <div class="fb-like" data-send="true" data-width="450" data-show-faces="false"></div> + {% endif %} </div> diff --git a/.themes/classic/source/_layouts/default.html b/.themes/classic/source/_layouts/default.html index 629468d3..f23b07b8 100644 --- a/.themes/classic/source/_layouts/default.html +++ b/.themes/classic/source/_layouts/default.html @@ -1,16 +1,14 @@ {% capture root_url %}{{ site.root | strip_slash }}{% endcapture %} {% include head.html %} -<body {% if page.body_id %} id="{{ page.body_id }}" {% endif %} {% if page.sidebar == false %} class="no-sidebar" {% endif %}> - <header>{% include header.html %}</header> - <nav role=navigation>{% include navigation.html %}</nav> +<body {% if page.body_id %} id="{{ page.body_id }}" {% endif %} {% if page.sidebar == false %} class="no-sidebar" {% endif %} {% if page.sidebar == 'collapse' or site.sidebar == 'collapse' %} class="collapse-sidebar sidebar-footer" {% endif %}> + <header role="banner">{% include header.html %}</header> + <nav role="navigation">{% include navigation.html %}</nav> <div id="main"> <div id="content"> {{ content | expand_urls: root_url }} </div> </div> - <footer>{% include footer.html %}</footer> - {% include google_analytics.html %} - {% include google_plus_one.html %} - {% include twitter_sharing.html %} + <footer role="contentinfo">{% include footer.html %}</footer> + {% include after_footer.html %} </body> </html> diff --git a/.themes/classic/source/_layouts/page.html b/.themes/classic/source/_layouts/page.html index dbf209c4..8ba6ec94 100644 --- a/.themes/classic/source/_layouts/page.html +++ b/.themes/classic/source/_layouts/page.html @@ -3,10 +3,10 @@ layout: default --- <div> -<article> +<article role="article"> {% if page.title %} <header> - <h1 class="entry-title">{{ page.title | titlecase }}</h1> + <h1 class="entry-title">{% if site.titlecase %}{{ page.title | titlecase }}{% else %}{{ page.title }}{% endif %}</h1> {% if page.date %}<p class="meta">{% include post/date.html %}{{ time }}</p>{% endif %} </header> {% endif %} @@ -27,12 +27,12 @@ layout: default {% if site.disqus_short_name and page.comments == true %} <section> <h1>Comments</h1> - <div id="disqus_thread">{% include post/disqus_thread.html %}</div> + <div id="disqus_thread" aria-live="polite">{% include post/disqus_thread.html %}</div> </section> {% endif %} </div> {% unless page.sidebar == false %} -<aside role=sidebar> +<aside class="sidebar"> {% if site.page_asides.size %} {% include_array page_asides %} {% else %} diff --git a/.themes/classic/source/_layouts/post.html b/.themes/classic/source/_layouts/post.html index ce8a5dea..40911680 100644 --- a/.themes/classic/source/_layouts/post.html +++ b/.themes/classic/source/_layouts/post.html @@ -4,7 +4,7 @@ single: true --- <div> -<article class="hentry"> +<article class="hentry" role="article"> {% include article.html %} <footer> <p class="meta"> @@ -15,17 +15,25 @@ single: true {% unless page.sharing == false %} {% include post/sharing.html %} {% endunless %} + <p class="meta"> + {% if page.previous.url %} + <a class="basic-alignment left" href="{{page.previous.url}}" title="Previous Post: {{page.previous.title}}">« {{page.previous.title}}</a> + {% endif %} + {% if page.next.url %} + <a class="basic-alignment right" href="{{page.next.url}}" title="Next Post: {{page.next.title}}">{{page.next.title}} »</a> + {% endif %} + </p> </footer> </article> -{% if site.disqus_short_name and page.comments != false %} +{% if site.disqus_short_name and page.comments == true %} <section> <h1>Comments</h1> - <div id="disqus_thread">{% include post/disqus_thread.html %}</div> + <div id="disqus_thread" aria-live="polite">{% include post/disqus_thread.html %}</div> </section> {% endif %} </div> {% unless page.sidebar == false %} -<aside role=sidebar> +<aside class="sidebar"> {% if site.post_asides.size %} {% include_array post_asides %} {% else %} diff --git a/.themes/classic/source/assets/jwplayer/glow/glow.xml b/.themes/classic/source/assets/jwplayer/glow/glow.xml index 7d5ba038..71bdced0 100644 --- a/.themes/classic/source/assets/jwplayer/glow/glow.xml +++ b/.themes/classic/source/assets/jwplayer/glow/glow.xml @@ -1,115 +1,115 @@ -<?xml version="1.0"?>
-<skin version="1.1" name="Glow" author="LongTail Video">
-
- <settings>
- <setting name="backcolor" value="0x000000" />
- <setting name="frontcolor" value="0xeeeeee" />
- <setting name="lightcolor" value="0xeeeeee" />
- <setting name="screencolor" value="0x000000" />
- </settings>
-
- <components>
- <component name="controlbar">
- <settings>
- <setting name="margin" value="0" />
- <setting name="fontsize" value="11" />
- <setting name="fontcolor" value="0xEEEEEE" />
- <setting name="buttoncolor" value="0xEEEEEE" />
- </settings>
-
- <layout>
- <group position="left">
- <button name="play" />
- <text name="elapsed" />
- </group>
- <group position="center">
- <slider name="time" />
- </group>
- <group position="right">
- <text name="duration" />
- <button name="blank" />
- <button name="mute" />
- <button name="fullscreen" />
- </group>
- </layout>
-
- <elements>
- <element name="background" src="background.png" />
- <element name="capLeft" src="divider.png" />
- <element name="capRight" src="divider.png" />
- <element name="divider" src="divider.png" />
- <element name="blankButton" src="blankButton.png" />
- <element name="fullscreenButton" src="fullscreenButton.png" />
- <element name="fullscreenButtonOver" src="fullscreenButtonOver.png" />
- <element name="muteButton" src="muteButton.png" />
- <element name="muteButtonOver" src="muteButtonOver.png" />
- <element name="pauseButton" src="pauseButton.png" />
- <element name="pauseButtonOver" src="pauseButtonOver.png" />
- <element name="playButton" src="playButton.png" />
- <element name="playButtonOver" src="playButtonOver.png" />
- <element name="timeSliderBuffer" src="timeSliderBuffer.png" />
- <element name="timeSliderCapLeft" src="timeSliderCapLeft.png" />
- <element name="timeSliderCapRight" src="timeSliderCapRight.png" />
- <element name="timeSliderProgress" src="timeSliderProgress.png" />
- <element name="timeSliderRail" src="timeSliderRail.png" />
- <element name="normalscreenButton" src="normalscreenButton.png" />
- <element name="normalscreenButtonOver" src="normalscreenButtonOver.png" />
- <element name="unmuteButton" src="unmuteButton.png" />
- <element name="unmuteButtonOver" src="unmuteButtonOver.png" />
- <element name="volumeSliderRail" src="divider.png" />
- <element name="volumeSliderProgress" src="divider.png" />
- </elements>
- </component>
-
- <component name="display">
- <settings>
- <setting name="bufferinterval" value="250" />
- <setting name="bufferrotation" value="90" />
- </settings>
- <elements>
- <element name="background" src="background.png" />
- <element name="playIcon" src="playIcon.png" />
- <element name="muteIcon" src="muteIcon.png" />
- <element name="errorIcon" src="bufferIcon.png" />
- <element name="bufferIcon" src="bufferIcon.png" />
- </elements>
- </component>
-
- <component name="dock">
- <settings>
- <setting name="fontcolor" value="0xFFFFFF" />
- </settings>
- <elements>
- <element name="button" src="button.png" />
- </elements>
- </component>
-
- <component name="playlist">
- <settings>
- <setting name="fontcolor" value="0xEEEEEE" />
- <setting name="overcolor" value="0xFFFFFF" />
- <setting name="activecolor" value="0xFFFFFF" />
- <setting name="backgroundcolor" value="0x333333" />
- </settings>
- <elements>
- <element name="item" src="item.png" />
- <element name="itemOver" src="itemOver.png" />
- <element name="sliderCapBottom" src="sliderCapBottom.png" />
- <element name="sliderCapTop" src="sliderCapTop.png" />
- <element name="sliderRail" src="sliderRail.png" />
- <element name="sliderThumb" src="sliderThumb.png" />
- </elements>
- </component>
-
- <component name="sharing">
- <elements>
- <element name="embedIcon" src="embedIcon.png" />
- <element name="embedScreen" src="embedScreen.png" />
- <element name="shareIcon" src="shareIcon.png" />
- <element name="shareScreen" src="shareScreen.png" />
- </elements>
- </component>
-
- </components>
-
+<?xml version="1.0"?> +<skin version="1.1" name="Glow" author="LongTail Video"> + + <settings> + <setting name="backcolor" value="0x000000" /> + <setting name="frontcolor" value="0xeeeeee" /> + <setting name="lightcolor" value="0xeeeeee" /> + <setting name="screencolor" value="0x000000" /> + </settings> + + <components> + <component name="controlbar"> + <settings> + <setting name="margin" value="0" /> + <setting name="fontsize" value="11" /> + <setting name="fontcolor" value="0xEEEEEE" /> + <setting name="buttoncolor" value="0xEEEEEE" /> + </settings> + + <layout> + <group position="left"> + <button name="play" /> + <text name="elapsed" /> + </group> + <group position="center"> + <slider name="time" /> + </group> + <group position="right"> + <text name="duration" /> + <button name="blank" /> + <button name="mute" /> + <button name="fullscreen" /> + </group> + </layout> + + <elements> + <element name="background" src="background.png" /> + <element name="capLeft" src="divider.png" /> + <element name="capRight" src="divider.png" /> + <element name="divider" src="divider.png" /> + <element name="blankButton" src="blankButton.png" /> + <element name="fullscreenButton" src="fullscreenButton.png" /> + <element name="fullscreenButtonOver" src="fullscreenButtonOver.png" /> + <element name="muteButton" src="muteButton.png" /> + <element name="muteButtonOver" src="muteButtonOver.png" /> + <element name="pauseButton" src="pauseButton.png" /> + <element name="pauseButtonOver" src="pauseButtonOver.png" /> + <element name="playButton" src="playButton.png" /> + <element name="playButtonOver" src="playButtonOver.png" /> + <element name="timeSliderBuffer" src="timeSliderBuffer.png" /> + <element name="timeSliderCapLeft" src="timeSliderCapLeft.png" /> + <element name="timeSliderCapRight" src="timeSliderCapRight.png" /> + <element name="timeSliderProgress" src="timeSliderProgress.png" /> + <element name="timeSliderRail" src="timeSliderRail.png" /> + <element name="normalscreenButton" src="normalscreenButton.png" /> + <element name="normalscreenButtonOver" src="normalscreenButtonOver.png" /> + <element name="unmuteButton" src="unmuteButton.png" /> + <element name="unmuteButtonOver" src="unmuteButtonOver.png" /> + <element name="volumeSliderRail" src="divider.png" /> + <element name="volumeSliderProgress" src="divider.png" /> + </elements> + </component> + + <component name="display"> + <settings> + <setting name="bufferinterval" value="250" /> + <setting name="bufferrotation" value="90" /> + </settings> + <elements> + <element name="background" src="background.png" /> + <element name="playIcon" src="playIcon.png" /> + <element name="muteIcon" src="muteIcon.png" /> + <element name="errorIcon" src="bufferIcon.png" /> + <element name="bufferIcon" src="bufferIcon.png" /> + </elements> + </component> + + <component name="dock"> + <settings> + <setting name="fontcolor" value="0xFFFFFF" /> + </settings> + <elements> + <element name="button" src="button.png" /> + </elements> + </component> + + <component name="playlist"> + <settings> + <setting name="fontcolor" value="0xEEEEEE" /> + <setting name="overcolor" value="0xFFFFFF" /> + <setting name="activecolor" value="0xFFFFFF" /> + <setting name="backgroundcolor" value="0x333333" /> + </settings> + <elements> + <element name="item" src="item.png" /> + <element name="itemOver" src="itemOver.png" /> + <element name="sliderCapBottom" src="sliderCapBottom.png" /> + <element name="sliderCapTop" src="sliderCapTop.png" /> + <element name="sliderRail" src="sliderRail.png" /> + <element name="sliderThumb" src="sliderThumb.png" /> + </elements> + </component> + + <component name="sharing"> + <elements> + <element name="embedIcon" src="embedIcon.png" /> + <element name="embedScreen" src="embedScreen.png" /> + <element name="shareIcon" src="shareIcon.png" /> + <element name="shareScreen" src="shareScreen.png" /> + </elements> + </component> + + </components> + </skin>
\ No newline at end of file diff --git a/.themes/classic/source/atom.xml b/.themes/classic/source/atom.xml index 693f3978..83af3f81 100644 --- a/.themes/classic/source/atom.xml +++ b/.themes/classic/source/atom.xml @@ -4,25 +4,24 @@ layout: nil <?xml version="1.0" encoding="utf-8"?> <feed xmlns="http://www.w3.org/2005/Atom"> - <title>{{ site.title }}</title> + <title><![CDATA[{{ site.title }}]]></title> <link href="{{ site.url }}/atom.xml" rel="self"/> <link href="{{ site.url }}/"/> <updated>{{ site.time | date_to_xmlschema }}</updated> <id>{{ site.url }}/</id> <author> - <name>{{ site.author }}</name> - {% if site.email %} - <email>{{ site.email }}</email> - {% endif %} + <name><![CDATA[{{ site.author | strip_html }}]]></name> + {% if site.email %}<email><![CDATA[{{ site.email }}]]></email>{% endif %} </author> + <generator uri="http://octopress.org/">Octopress</generator> {% for post in site.posts limit: 20 %} <entry> - <title>{{ post.title }}</title> + <title type="html"><![CDATA[{{ post.title | cdata_escape }}]]></title> <link href="{{ site.url }}{{ post.url }}"/> <updated>{{ post.date | date_to_xmlschema }}</updated> <id>{{ site.url }}{{ post.id }}</id> - <content type="html">{{ post.content | expand_urls: site.url | xml_escape }}</content> + <content type="html"><![CDATA[{{ post.content | expand_urls: site.url | cdata_escape }}]]></content> </entry> {% endfor %} </feed> diff --git a/.themes/classic/source/index.html b/.themes/classic/source/index.html index e7e96956..a114e5a8 100644 --- a/.themes/classic/source/index.html +++ b/.themes/classic/source/index.html @@ -3,15 +3,14 @@ layout: default --- <div class="blog-index"> -{% assign index = true %} -{% for post in paginator.posts %} -{% assign content = post.content %} - <article> - {% include article.html %} - </article> -{% endfor %} -<nav role="pagination"> - <div> + {% assign index = true %} + {% for post in paginator.posts %} + {% assign content = post.content %} + <article> + {% include article.html %} + </article> + {% endfor %} + <div class="pagination"> {% if paginator.next_page %} <a class="prev" href="{{paginator.next_page}}">← Older</a> {% endif %} @@ -20,20 +19,8 @@ layout: default <a class="next" href="{{paginator.previous_page}}">Newer →</a> {% endif %} </div> -</nav> -{% if site.disqus_short_name %} -<script type="text/javascript"> - var disqus_shortname = '{{ site.disqus_short_name }}'; - (function () { - var s = document.createElement('script'); s.async = true; - s.type = 'text/javascript'; - s.src = 'http://' + disqus_shortname + '.disqus.com/count.js'; - (document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s); - }()); -</script> -{% endif %} </div> -<aside role=sidebar> +<aside class="sidebar"> {% if site.blog_index_asides.size %} {% include_array blog_index_asides %} {% else %} diff --git a/.themes/classic/source/javascripts/ender.js b/.themes/classic/source/javascripts/ender.js index 9958885a..1add349c 100644 --- a/.themes/classic/source/javascripts/ender.js +++ b/.themes/classic/source/javascripts/ender.js @@ -1,2 +1,45 @@ -eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('!5(O){5 2j(o,42){F(u k Y 42){k!=\'28\'&&k!=\'4T\'&&(o[k]=42[k])}7 o}5 2P(s,r){u R;B(X.4E&&N s==\'1p\'||s.4R||s.E&&\'3g\'Y s||s==1O){R=X.4E(s,r);R.H=s}1h{R=5F(s.E)?s:[s]}7 2j(R,2P)}5 X(s,r){7 2P(s,r)}2j(X,{4T:\'0.2.0\',X:5(o,4Z){2j(4Z?2P:X,o)}});2j(2P,{6E:5(D,1Z){F(u i=0,l=8.E;i<l;++i){i Y 8&&D.11(1Z||8[i],8[i],i,8)}7 8}});u 3d=O.$;X.28=5(){O.$=3d;7 8};(N 1v!==\'1w\')&&1v.1y&&(1v.1y=X);O[\'X\']=O[\'$\']=X}(8);!5(O){u 2a=1,3q={},2t={},5y=/6x|6r/,2O=/[^\\.]*(?=\\..*)\\.|.*/,2C=/\\..*/,3z=\'2X\',2h=\'2h\',59=\'6a\',3A=\'3A\',I=O.1f||{},V=I.2H||{},2f=V[3z],39=2f?3z:2h,5g=5(57,5t){u G=5t.18;1d(G!=1e){B(G==57){7 19}G=G.18}},3F=5(22,L){7(22.2a=L||22.2a||2a++)},2l=5(A){u L=3F(A);7(3q[L]=3q[L]||{})},4F=2f?5(A,C,D,S){A[S?3z:59](C,D,1i)}:5(A,C,D,S,1J){1J&&S&&(A[\'3b\'+1J]=A[\'3b\'+1J]||0);A[S?2h:3A](\'3L\'+C,D)},5f=5(A,D,17){7 5(1m){1m=2w(1m||((8.6F||8.1f||8).7h||O).1m);7 D.1V(A,[1m].31(17))}},4z=5(A,D,C,1z,17){7 5(1m){B(1z?1z.11(8,1m):2f?19:1m&&1m.78==\'3b\'+C||!1m){D.1V(A,[1m].31(17))}}},4h=5(A,2x,D,17){u C=2x.1g(2C,\'\'),J=2l(A),1L=J[C]||(J[C]={}),L=3F(D,2x.1g(2O,\'\'));B(1L[L]){7 A}u 1J=36[C];B(1J){D=1J.1z?4z(A,D,C,1J.1z):D;C=1J.2S||C}u 15=34[C];D=15?5f(A,D,17):4z(A,D,C,1i,17);15=2f||15;B(C==\'2J\'){u 5b=D;D=5(){3t(A,C,D)&&5b()}}A[39]&&4F(A,15?C:\'54\',D,19,!15&&C);1L[L]=D;D.2a=L;7 C==\'2J\'?A:(2t[3F(A)]=A)},3t=5(A,2x,3C){u L,2q,3G,i,J=2l(A),C=2x.1g(2C,\'\');B(!J||!J[C]){7 A}2q=2x.1g(2O,\'\');3G=2q?2q.2b(\'.\'):[3C.2a];F(i=3G.E;i--;){L=3G[i];3C=J[C][L];2k J[C][L];B(A[39]){C=36[C]?36[C].2S:C;u 15=2f||34[C];4F(A,15?C:\'54\',3C,1i,!15&&C)}}7 A},4V=5(H,D,$){7 5(e){u 1R=N H==\'1p\'?$(H,8):H;F(u M=e.M;M&&M!=8;M=M.18){F(u i=1R.E;i--;){B(1R[i]==M){7 D.1V(M,3p)}}}}},S=5(A,J,D,5a,$){B(N J==\'68\'&&!D){F(u C Y J){J.1T(C)&&S(A,C,J[C])}}1h{u 3v=N D==\'1p\',2d=(3v?D:J).2b(\' \');D=3v?4V(J,5a,$):D;F(u i=2d.E;i--;){4h(A,2d[i],D,5l.2g.3u.11(3p,3v?4:3))}}7 A},1o=5(A,1u,D){u k,C,J,2s=N(1u)==\'1p\',2q=2s&&1u.1g(2O,\'\'),2u=3t,2G=2l(A);B(2s&&/\\s/.12(1u)){1u=1u.2b(\' \');u i=1u.E-1;1d(1o(A,1u[i])&&i--){}7 A}J=2s?1u.1g(2C,\'\'):1u;B(!2G||(2s&&!2G[J])){7 A}B(N D==\'5\'){2u(A,J,D)}1h B(2q){2u(A,1u)}1h{2u=J?2u:1o;C=2s&&J;J=J?(D||2G[J]||J):2G;F(k Y J){J.1T(k)&&2u(A,C||k,J[k])}}7 A},1P=5(A,C,17){u 38,k,i,2d=C.2b(\' \');F(i=2d.E;i--;){C=2d[i].1g(2C,\'\');u 15=34[C],24=2d[i].1g(2O,\'\'),1L=2l(A)[C];B(24){24=24.2b(\'.\');F(k=24.E;k--;){1L[24[k]]&&1L[24[k]].1V(A,17)}}1h B(!17&&A[39]){4S(15,C,A)}1h{F(k Y 1L){1L.1T(k)&&1L[k].1V(A,17)}}}7 A},4S=2f?5(15,C,A){38=1f.76(15?"6X":"6W");38[15?\'6Y\':\'6Z\'](C,19,19,O,1);A.70(38)}:5(15,C,A){15?A.6U(\'3L\'+C,1f.6P()):A[\'3b\'+C]++},2F=5(A,32,C){u J=2l(32),22,k;22=C?J[C]:J;F(k Y 22){22.1T(k)&&(C?S:2F)(A,C||32,C?22[k]:k)}7 A},2w=5(e){u T={};B(!e){7 T}u C=e.C,M=e.M||e.7d;T.2U=2w.2U(e);T.2R=2w.2R(e);T.M=M&&M.1j==3?M.18:M;B(~C.4A(\'7c\')){T.5u=e.5s||e.5u}1h B((/3R|7e|7f/i).12(C)){T.7g=e.5s==3||e.7a==2;T.75={x:0,y:0};B(e.5r||e.5x){T.37=e.5r;T.35=e.5x}1h B(e.37||e.35){T.37=e.37+1f.3M.2y+1f.2H.2y;T.35=e.35+1f.3M.2z+1f.2H.2z}5y.12(C)&&(T.4v=e.4v||e[(C==\'3i\'?\'32\':\'6u\')+\'6t\'])}F(u k Y e){B(!(k Y T)){T[k]=e[k]}}7 T};2w.2U=5(e){7 5(){B(e.2U){e.2U()}1h{e.6w=1i}}};2w.2R=5(e){7 5(){B(e.2R){e.2R()}1h{e.6n=19}}};u 34={3R:1,5z:1,5D:1,5p:1,6M:1,3O:1,5i:1,3i:1,4f:1,6z:1,6K:1,6L:1,5B:1,5w:1,5v:1,6G:1,6A:1,6C:1,6D:1,6I:1,6B:1,6H:1,6p:1,5C:1,5n:1,5o:1,6o:1,2r:1,4N:1,5q:1,2J:1,6m:1,4I:1,6q:1,6b:1,72:1,5A:1,7o:1,2N:1};5 4x(1m){u 1F=1m.4v;B(!1F){7 1F==1e}7(1F!=8&&1F.7X!=\'7i\'&&!/1f/.12(8.80())&&!5g(8,1F))}u 36={3V:{2S:\'3i\',1z:4x},48:{2S:\'4f\',1z:4x},3O:{2S:/7W/.12(4O.55)?\'5i\':\'3O\'}};u 1Y={S:S,1o:1o,2F:2F,1P:1P};u 1X=5(6){u L=1o(6).2a;B(L){2k 2t[L];2k 3q[L]}};B(O[2h]){S(O,\'2J\',5(){F(u k Y 2t){2t.1T(k)&&1X(2t[k])}O.5j&&5j()})}u 5k=O.1Y;1Y.28=5(){O.1Y=5k;7 8};(N 1v!==\'1w\'&&1v.1y)?(1v.1y=1Y):(O[\'1Y\']=1Y)}(8);!5($){u b=1Y.28(),2v=5(1B,C,83){u 5m=C?[C]:[];7 5(){F(u 17,i=0,l=8.E;i<l;i++){17=[8[i]].31(5m,5l.2g.3u.11(3p,0));17.E==4&&17.13($);!3p.E&&1B==\'S\'&&C&&(1B=\'1P\');b[1B].1V(8,17)}7 8}};u S=2v(\'S\'),1o=2v(\'1o\'),1P=2v(\'1P\');u 3X={3L:S,4h:S,8e:S,8f:S,8g:S,8b:1o,8c:1o,3t:1o,85:1o,84:1P,87:1P,8a:2v(\'2F\'),89:5(5e,5d){F(u i=0,l=8.E;i<l;i++){b.S.11(8,8[i],\'3V\',5e);b.S.11(8,8[i],\'48\',5d)}7 8}};u 46=[\'5n\',\'5o\',\'3R\',\'5z\',\'5A\',\'5C\',\'7v\',\'7q\',\'5B\',\'5w\',\'5v\',\'5q\',\'5p\',\'3V\',\'48\',\'4f\',\'3i\',\'5D\',\'4I\',\'2N\',\'2r\',\'4N\',\'2J\'];F(u i=46.E;i--;){u 3Z=46[i];3X[3Z]=2v(\'S\',3Z)}$.X(3X,19)}(X);!5(O){u I=O.1f,W=I.2H,2n=1e,7I=\'3o\',5J=/^52|1l|53$/,6e=/2r|3s|7H|56|51|4Y|7J/i,5Z={2r:\'7K\',56:\'51\',4Y:\'7G\'},5S=/^52|53$/,2M=/7B/i.12(4O.55),2Q=[],3K=0,5H=/^-?[\\d\\.]+$/,2V=\'2V\',2Y=\'2Y\',1S=\'1S\',4X=/(^\\s*|\\s*$)/g,5I={7D:1,4b:1,7C:1,1Q:1};5 2B(c){7 1a 1E("(^|\\\\s+)"+c+"(\\\\s+|$)")}5 K(Q,D,1Z){F(u i=0,l=Q.E;i<l;i++){D.11(1Z||Q[i],Q[i],i,Q)}7 Q}u 2c=7z.2g.2c?5(s){7 s.2c()}:5(s){7 s.1g(4X,\'\')};5 2K(s){7 s.1g(/-(.)/g,5(m,5E){7 5E.7A()})}5 4k(G){7 G&&G.4R&&G.1j==1}5 6c(Q,D,1Z){F(u i=0,j=Q.E;i<j;++i){B(D.11(1Z,Q[i],i,Q)){7 19}}7 1i}u 5Q=I.40&&I.40.4P?5(6,14){u 1l=1e;B(14==\'3n\'){14=\'5G\'}u 44=I.40.4P(6,\'\');44&&(1l=44[2K(14)]);7 6.1t[14]||1l}:(2M&&W.49)?5(6,14){14=2K(14);14=14==\'3n\'?\'5L\':14;B(14==\'1Q\'){u P=4c;4H{P=6.4U[\'7p.7w.88\'].1Q}3S(82){4H{P=6.4U(\'5M\').1Q}3S(7T){}}7 P/4c}u 1l=6.49?6.49[14]:1e;7 6.1t[14]||1l}:5(6,14){7 6.1t[2K(14)]};5 2T(M,1r,D){u i=0,21=1r||8,r=[];K(2L(2n?2n(M):M),5(t){K(21,5(6){u n=6.66(19);D(t,n);r[i]=n;i++})},8);K(r,5(e,i){21[i]=e});21.E=i;7 21}5 5K(6,x,y){u $6=U(6),1t=$6.1M(\'6k\'),2W=$6.2W(),3l=\'7Q\',43=1t==3l,2e=[3a($6.1M(\'1H\'),10),3a($6.1M(\'1G\'),10)];B(1t==\'7Z\'){$6.1M(\'6k\',3l);1t=3l}69(2e[0])&&(2e[0]=43?0:6.3I);69(2e[1])&&(2e[1]=43?0:6.3J);x!==1e&&(6.1t.1H=x-2W.1H+2e[0]+\'2V\');y!==1e&&(6.1t.1G=y-2W.1G+2e[1]+\'2V\')}5 3f(1k){8.E=0;8.7m=1k;B(1k){1k=N 1k!==\'1p\'&&!1k.1j&&N 1k.E!==\'1w\'?1k:[1k];8.E=1k.E;F(u i=0;i<1k.E;i++){8[i]=1k[i]}}}3f.2g={K:5(D,1Z){7 K(8,D,1Z)},3s:5(D,41){u m=[],n,i;F(i=0;i<8.E;i++){n=D.11(8,8[i]);41?(41(n)&&m.13(n)):m.13(n)}7 m},3c:5(){7 U(8[0])},5N:5(){7 U(8[8.E-1])},W:5(h,2I){u 1B=2I?W.6h==1e?\'7L\':\'6h\':\'4j\',m;5 45(6,1n){1d(6.1C){6.3r(6.1C)}K(2L(h,1n),5(G){6.2m(G)})}7 N h!==\'1w\'?8.K(5(6){(m=6.3T.1c(6e))?45(6,m[0]):(6[1B]=h)}):8[0]?8[0][1B]:\'\'},2I:5(2I){7 8.W(2I,1)},7r:5(c){7 8.K(5(6){8.3j(6,c)||(6.1q=2c(6.1q+\' \'+c))},8)},7E:5(c){7 8.K(5(6){8.3j(6,c)&&(6.1q=2c(6.1q.1g(2B(c),\' \')))},8)},3j:5(6,c){7 N c==\'1w\'?6c(8,5(i){7 2B(6).12(i.1q)}):2B(c).12(6.1q)},7F:5(c,1z){B(N 1z!==\'1w\'&&!1z){7 8}7 8.K(5(6){8.3j(6,c)?(6.1q=2c(6.1q.1g(2B(c),\' \'))):(6.1q=2c(6.1q+\' \'+c))},8)},7M:5(C){7 8.K(5(6){6.1t.5O=C||\'\'})},7y:5(1k){7 8.K(5(6){6.1t.5O=\'7x\'})},45:5(G){7 8.K(5(6){K(2L(G),5(i){6.2m(i)})})},7n:5(G){7 8.K(5(6){u 3c=6.1C;K(2L(G),5(i){6.1K(i,3c)})})},4q:5(M,1r){7 2T.11(8,M,1r,5(t,6){t.2m(6)})},4m:5(M,1r){7 2T.11(8,M,1r,5(t,6){t.1K(6,t.1C)})},4p:5(){7 8.1F(\'25\')},4u:5(){7 8.1F(\'67\')},1F:5(1B){7 8.3s(5(6){6=6[1B];1d(6&&6.1j!==1){6=6[1B]}7 6||0},5(6){7 6})},7l:5(G){7 8.K(5(6){K(U.20(G),5(i){6.18.1K(i,6)})})},7j:5(G){7 8.K(5(6){K(U.20(G),5(i){6.18.1K(i,6.25)})})},1K:5(M,1r){7 2T.11(8,M,1r,5(t,6){t.18.1K(6,t)})},4r:5(M,1r){7 2T.11(8,M,1r,5(t,6){u 4e=t.25;B(4e){t.18.1K(6,4e)}1h{t.18.2m(6)}})},1M:5(o,v){B(v===1w&&N o==\'1p\'){7 5Q(8[0],o)}u 1b=o;B(N o==\'1p\'){1b={};1b[o]=v}B(2M&&1b.1Q){1b.7k=\'5M(1Q=\'+(1b.1Q*4c)+\')\';1b.4b=o.4b||1;2k 1b.1Q}B(v=1b[\'3n\']){2M?(1b.5L=v):(1b.5G=v);2k 1b[\'3n\']}u D=5(6,p,v){F(u k Y 1b){B(1b.1T(k)){v=1b[k];(p=2K(k))&&5H.12(v)&&!(p Y 5I)&&(v+=2V);6.1t[p]=v}}};7 8.K(D)},2W:5(x,y){B(x||y){7 8.K(5(6){5K(6,x,y)})}u 6=8[0];u 1N=6.7u;u 1I=6.7t;u 1G=6.3J;u 1H=6.3I;1d(6=6.7O){1G=1G+6.3J;1H=1H+6.3I}7{1G:1G,1H:1H,1I:1I,1N:1N}},3y:5(k,v){u 6=8[0];7 N v==\'1w\'?5J.12(k)?5S.12(k)&&N 6[k]==\'1p\'?19:6[k]:6[1S](k):8.K(5(6){k==\'1l\'?(6.1l=v):6[2Y](k,v)})},P:5(s){7(N s==\'1p\')?8.3y(\'1l\',s):8[0].1l},7s:5(k){7 8.K(5(6){6.7N(k)})},26:5(k,v){u 6=8[0];B(N v===\'1w\'){6[1S](\'26-G-L\')||6[2Y](\'26-G-L\',++3K);u L=6[1S](\'26-G-L\');2Q[L]||(2Q[L]={});7 2Q[L][k]}1h{7 8.K(5(6){6[1S](\'26-G-L\')||6[2Y](\'26-G-L\',++3K);u L=6[1S](\'26-G-L\');u o={};o[k]=v;2Q[L]=o})}},1o:5(){7 8.K(5(6){6.18&&6.18.3r(6)})},8d:5(){7 8.K(5(6){1d(6.1C){6.3r(6.1C)}})},86:5(){7 8.3s(5(6){7 6.18.3r(6)})},2z:5(y){7 2N.11(8,1e,y,\'y\')},2y:5(x){7 2N.11(8,x,1e,\'x\')}};5 2L(G,1n){7 N G==\'1p\'?U.20(G,1n):4k(G)?[G]:G}5 2N(x,y,C){u 6=8[0];B(x==1e&&y==1e){7(3P(6)?5U():{x:6.2y,y:6.2z})[C]}B(3P(6)){1O.7U(x,y)}1h{x!=1e&&(6.2y=x);y!=1e&&(6.2z=y)}7 8}5 3P(A){7 A===1O||(/^(?:3M|W)$/i).12(A.3T)}5 5U(){7{x:1O.7S||W.2y,y:1O.7V||W.2z}}5 U(R,1r){7 1a 3f(R,1r)}U.4C=5(q){2n=q;2k U.4C};U.2j=5(o,M){F(u k Y o){o.1T(k)&&((M||3f.2g)[k]=o[k])}};U.20=5(G,1n){7 N G==\'1p\'?5(){u t=1n?5Z[1n.6f()]:1e;u 6=I.3e(t||\'4L\'),R=[];B(1n){u 5Y=G.1c(1a 1E("<"+t+">.+?<\\\\/"+t+">","g"));K(5Y,5(m){m=m.1g(/<(.+)>(.+?)<\\/\\1>/,\'$2\');u 4l=I.3e(t);4l.2m(I.7Y(m));6.2m(4l)})}1h{6.4j=G}u 4Q=6.4y;6=6.1C;R.13(6);1d(6=6.25){(6.1j==1)&&R.13(6)}7 R}():4k(G)?[G.66(19)]:[]};U.I=5(){u w=W.6s,h=W.6v,4s=8.63();7{1N:65.62(w,4s.1N),1I:65.62(h,4s.1I)}};U.1C=5(6){F(u c=6.4y,i=0,j=(c&&c.E)||0,e;i<j;i++){B(c[i].1j===1){e=c[j=i]}}7 e};U.63=5(){u h=21.77,w=21.6N;2M&&(h=W.74)&&(w=W.7b);7{1N:w,1I:h}};U.33=\'3k\'Y W?5(Z,A){7(Z.3k(A)&16)==16}:\'3m\'Y W?5(Z,A){7 Z!==A&&Z.3m(A)}:5(Z,A){1d(A=A.18){B(A===Z){7 19}}7 1i};u 3d=O.U;U.28=5(){O.U=3d;7 8};O[\'U\']=U}(8);!5($){u b=U;b.4C($);$.X(b);$.X(b(),19);$.X({20:5(G){7 $(b.20(G))}});$.2i=5(2i){7 $([1f.47(2i)])};5 4A(Q,P){F(u i=0;i<Q.E;i++){B(Q[i]===P){7 i}}7-1}5 1U(Q){u a=[],i,j;3h:F(i=0;i<Q.E;i++){F(j=0;j<a.E;j++){B(a[j]==Q[i]){3Y 3h}}a[a.E]=Q[i]}7 a}$.X({5R:5(H,4o){u 29=$(H),j,k,p,r=[];F(j=0,k=8.E;j<k;j++){p=8[j];1d(p=p.18){B(4A(29,p)!==-1){r.13(p);B(4o)5T}}}7 $(1U(r))},4o:5(H){7 8.5R(H,19)},3c:5(){7 $(8[0])},5N:5(){7 $(8[8.E-1])},4p:5(){7 $(b(8).4p())},4u:5(){7 $(b(8).4u())},4q:5(t){7 b(8.H).4q(t,8)},4m:5(t){7 b(8.H).4m(t,8)},4r:5(t){7 b(8.H).4r(t,8)},1K:5(t){7 b(8.H).1K(t,8)},6V:5(){u i,l,p,r=[];F(i=0,l=8.E;i<l;i++){p=8[i];1d(p=p.67){p.1j==1&&r.13(p)}p=8[i];1d(p=p.25){p.1j==1&&r.13(p)}}7 $(r)},71:5(){u 6,r=[];F(i=0,l=8.E;i<l;i++){B(!(6=b.1C(8[i]))){3Y}r.13(6);1d(6=6.25){6.1j==1&&r.13(6)}}7 $(1U(r))},1I:5(v){7 v?8.1M(\'1I\',v):3a(8.1M(\'1I\'),10)},1N:5(v){7 v?8.1M(\'1N\',v):3a(8.1M(\'1N\'),10)}},19)}(X||$);!5(){u 1y={},1v={1y:1y};!5(I){u 2D=0,2E=[],3E,f=1i,3D=I.3e(\'a\'),4w=\'6b\',2X=\'2X\',3B=\'3B\';/^6S|c/.12(I.6d)&&(2D=1);5 4D(){2D=1;F(u i=0,l=2E.E;i<l;i++){2E[i]()}}I[2X]&&I[2X](4w,5 D(){I.6a(4w,D,f);4D()},f);3D.3N&&I.2h(3B,(3E=5 3E(){B(/^c/.12(I.6d)){I.3A(3B,3E);4D()}}));u 2p=3D.3N?5(D){21!=1G?!2D?2E.13(D):D():!5(){4H{3D.3N(\'1H\')}3S(e){7 79(5(){2p(D)},50)}D()}()}:5(D){2D?D():2E.13(D)};(N 1v!==\'1w\')&&1v.1y?(1v.1y={2p:2p}):(1O.2p=2p)}(1f);$.X(1v.1y)}.11($);!5(O,I){u c,i,j,k,l,m,o,p,r,v,6,G,3W,4g,3x,3g,1W,4B,2i=/#([\\w\\-]+)/,6j=/\\.[\\w\\-]+/g,4a=/^#([\\w\\-]+$)/,4M=/^\\.([\\w\\-]+)$/,5P=/^([\\w\\-]+)$/,5c=/^([\\w]+)?\\.([\\w\\-]+)$/,W=I.2H,61=/\\s(?![\\s\\w\\-\\/\\?\\&\\=\\:\\.\\(\\)\\!,@#%<>\\{\\}\\$\\*\\^\'"]*\\])/,5X=/([.*+?\\^=!:${}()|\\[\\]\\/\\\\])/g,4W=/^([a-6J-9]+)?(?:([\\.\\#]+[\\w\\-\\.#]+)?)/,3y=/\\[([\\w\\-]+)(?:([\\|\\^\\$\\*\\~]?\\=)[\'"]?([ \\w\\-\\/\\?\\&\\=\\:\\.\\(\\)\\!,@#%<>\\{\\}\\$\\*\\^]+)["\']?)?\\]/,6g=1a 1E(4W.6l+\'(\'+3y.6l+\')?\');5 1R(Q){r=[];F(i=0,3W=Q.E;i<3W;i++){r[i]=Q[i]}7 r}u 2o=5(){8.c={}};2o.2g={g:5(k){7 8.c[k]||1w},s:5(k,v){8.c[k]=v;7 v}};u 30=1a 2o(),4i=1a 2o(),1x=1a 2o(),3Q=1a 2o();5 q(2n){7 2n.1c(6g)}5 3H(6y,1n,2Z,4t,4n,60,1l){u m,c,k;B(1n&&8.3T.6f()!==1n){7 1i}B(2Z&&(m=2Z.1c(2i))&&m[1]!==8.2i){7 1i}B(2Z&&(3x=2Z.1c(6j))){F(i=3x.E;i--;){c=3x[i].3u(1);B(!(30.g(c)||30.s(c,1a 1E(\'(^|\\\\s+)\'+c+\'(\\\\s+|$)\'))).12(8.1q)){7 1i}}}B(4t&&!1l){o=8.6T;F(k Y o){B(6O.2g.1T.11(o,k)&&(o[k].73||k)==4n){7 8}}}B(4t&&!5W(60,8.1S(4n)||\'\',1l)){7 1i}7 8}5 64(1s){u r=[],4B=1s.81(),4G=q(4B),1n=4G[1]||\'*\',i,l,R,V=1s.E&&(m=1s[0].1c(4a))?I.47(m[1]):I;B(!V){7 r}R=V.3o(1n);F(i=0,l=R.E;i<l;i++){6=R[i];B(3g=3H.1V(6,4G)){r.13(3g)}}7 r}5 1X(s){7 4i.g(s)||4i.s(s,s.1g(5X,\'\\\\$1\'))}5 5W(5V,23,P){7P(5V){2A\'=\':7 23==P;2A\'^=\':7 23.1c(1x.g(\'^=\'+P)||1x.s(\'^=\'+P,1a 1E(\'^\'+1X(P))));2A\'$=\':7 23.1c(1x.g(\'$=\'+P)||1x.s(\'$=\'+P,1a 1E(1X(P)+\'$\')));2A\'*=\':7 23.1c(1x.g(P)||1x.s(P,1a 1E(1X(P))));2A\'~=\':7 23.1c(1x.g(\'~=\'+P)||1x.s(\'~=\'+P,1a 1E(\'(?:^|\\\\s+)\'+1X(P)+\'(?:\\\\s+|$)\')));2A\'|=\':7 23.1c(1x.g(\'|=\'+P)||1x.s(\'|=\'+P,1a 1E(\'^\'+1X(P)+\'(-|$)\')))}7 1i}5 5h(H){u r=[],27=[],i,l,1s=3Q.g(H)||3Q.s(H,H.2b(61));1s=1s.3u(0);B(!1s.E){7 r}r=64(1s);B(!1s.E){7 r}F(j=0,l=r.E,k=0;j<l;j++){G=r[j];p=G;F(i=1s.E;i--;){z:1d(p!==W&&(p=p.18)){B(4g=3H.1V(p,q(1s[i]))){5T z}}}4g&&(27[k++]=G)}7 27}5 6i(H,1A,D){u V=(N 1A==\'1p\')?D(1A)[0]:(1A||I);B(H===1O||4d(H)){7!1A||(H!==1O&&4d(V)&&33(H,V))?[H]:[]}B(H&&N H===\'68\'&&5F(H.E)){7 1R(H)}B(m=H.1c(4a)){7(6=I.47(m[1]))?[6]:[]}B(m=H.1c(5P)){7 1R(V.3o(m[1]))}7 1i}5 4d(6){7(6&&6.1j&&(6.1j==1||6.1j==9))}5 1U(Q){u a=[],i,j;3h:F(i=0;i<Q.E;i++){F(j=0;j<a.E;j++){B(a[j]==Q[i]){3Y 3h}}a[a.E]=Q[i]}7 a}5 1D(H,1A){u V=(N 1A==\'1p\')?1D(1A)[0]:(1A||I);B(!V||!H){7[]}B(m=6i(H,1A,1D)){7 m}7 2r(H,V)}u 33=\'3k\'Y W?5(A,Z){7(Z.3k(A)&16)==16}:\'3m\'Y W?5(A,Z){Z=Z==I||Z==1O?W:Z;7 Z!==A&&Z.3m(A)}:5(A,Z){1d(A=A.18){B(A===Z){7 1}}7 0},2r=(I.7R&&I.4K)?5(H,V){B(I.4J&&(m=H.1c(4M))){7 1R((V).4J(m[1]))}7 1R((V).4K(H))}:5(H,V){u T=[],29,3w=[],i;B(m=H.1c(5c)){1W=V.3o(m[1]||\'*\');r=30.g(m[2])||30.s(m[2],1a 1E(\'(^|\\\\s+)\'+m[2]+\'(\\\\s+|$)\'));F(i=0,l=1W.E,j=0;i<l;i++){r.12(1W[i].1q)&&(T[j++]=1W[i])}7 T}F(i=0,1W=H.2b(\',\'),l=1W.E;i<l;i++){3w[i]=5h(1W[i])}F(i=0,l=3w.E;i<l&&(29=3w[i]);i++){u 27=29;B(V!==I){27=[];F(j=0,m=29.E;j<m&&(A=29[j]);j++){33(A,V)&&27.13(A)}}T=T.31(27)}7 1U(T)};1D.1U=1U;u 58=O.1D;1D.28=5(){O.1D=58;7 8};O[\'1D\']=1D}(8,1f);!5(I){u q=1D.28();5 20(G,V){u 6=(V||I).3e(\'4L\'),R=[];6.4j=G;u 4Q=6.4y;6=6.1C;R.13(6);1d(6=6.25){(6.1j==1)&&R.13(6)}7 R};$.4E=5(s,r){7/^\\s*</.12(s)?20(s,r):q(s,r)};$.X({6Q:5(s){u r=[],i,l,j,k,R;F(i=0,l=8.E;i<l;i++){R=q(s,8[i]);F(j=0,k=R.E;j<k;j++){r.13(R[j])}}7 $(q.1U(r))},6R:5(s){u 3U=$(s);F(u i=8.E,j=0,l=8.E+3U.E;i<l;i++,j++){8[i]=3U[j]}7 8}},19)}(1f);',62,513,'|||||function|el|return|this||||||||||||||||||||||var||||||element|if|type|fn|length|for|node|selector|doc|events|each|uid|target|typeof|context|val|ar|els|add|result|bonzo|root|html|ender|in|container||call|test|push|property|isNative||args|parentNode|true|new|iter|match|while|null|document|replace|else|false|nodeType|elements|value|event|tag|remove|string|className|host|tokens|style|orgEvents|module|undefined|attrCache|exports|condition|_root|method|firstChild|qwery|RegExp|related|top|left|height|custom|insertBefore|handlers|css|width|window|fire|opacity|array|getAttribute|hasOwnProperty|uniq|apply|items|clean|bean|scope|create|self|obj|actual|isNamespace|nextSibling|data|ret|noConflict|collection|__uid|split|trim|types|delta|W3C_MODEL|prototype|attachEvent|id|aug|delete|retrieveEvents|appendChild|query|cache|domReady|names|select|isString|collected|rm|integrate|fixEvent|orgType|scrollLeft|scrollTop|case|classReg|stripName|loaded|fns|clone|attached|documentElement|text|unload|camelize|normalize|ie|scroll|namespace|boosh|uidList|stopPropagation|base|insert|preventDefault|px|offset|addEventListener|setAttribute|idsAndClasses|classCache|concat|from|isAncestor|nativeEvents|clientY|customEvents|clientX|evt|eventSupport|parseInt|_on|first|old|createElement|Bonzo|item|label|mouseover|hasClass|compareDocumentPosition|rel|contains|float|getElementsByTagName|arguments|registry|removeChild|map|removeListener|slice|isDel|collections|classes|attr|addEvent|detachEvent|onreadystatechange|handler|testEl|ol|retrieveUid|uids|interpret|offsetLeft|offsetTop|uuids|on|body|doScroll|mousewheel|isBody|tokenCache|click|catch|tagName|plus|mouseenter|len|methods|continue|shortcut|defaultView|reject|o2|isRel|computed|append|shortcuts|getElementById|mouseleave|currentStyle|idOnly|zoom|100|isNode|sibling|mouseout|found|addListener|cleanCache|innerHTML|is|bah|prependTo|attribute|closest|next|appendTo|insertAfter|vp|wholeAttribute|previous|relatedTarget|domContentLoaded|check|childNodes|customHandler|indexOf|token|setQueryEngine|flush|_select|listener|intr|try|resize|getElementsByClassName|querySelectorAll|div|classOnly|submit|navigator|getComputedStyle|nodes|nodeName|fireListener|_VERSION|filters|del|simple|trimReplace|tr|chain||tbody|checked|selected|propertychange|userAgent|table|parent|oldQwery|removeEvent|delfn|org|tagAndOrClass|leave|enter|nativeHandler|isDescendant|_qwery|DOMMouseScroll|CollectGarbage|oldBean|Array|_args|blur|change|mousedown|load|pageX|which|child|keyCode|keyup|keypress|pageY|overOut|dblclick|error|keydown|focus|mouseup|m1|isFinite|cssFloat|digit|unitless|specialAttributes|xy|styleFloat|alpha|last|display|tagOnly|getStyle|parents|stateAttributes|break|getWindowScroll|qualify|checkAttr|specialChars|bitches|tagMap|qualifier|tokenizr|max|viewport|loopAll|Math|cloneNode|previousSibling|object|isNaN|removeEventListener|DOMContentLoaded|some|readyState|specialTags|toLowerCase|chunker|textContent|boilerPlate|clas|position|source|beforeunload|cancelBubble|reset|gestureend|move|out|scrollWidth|Element|to|scrollHeight|returnValue|over|whole|mousemove|touchstart|gesturestart|touchmove|touchend|forEach|ownerDocument|orientationchange|gesturechange|touchcancel|z0|selectstart|selectend|contextmenu|innerWidth|Object|createEventObject|find|and|loade|attributes|fireEvent|siblings|UIEvents|HTMLEvents|initEvent|initUIEvent|dispatchEvent|children|readystatechange|name|clientHeight|pos|createEvent|innerHeight|propertyName|setTimeout|button|clientWidth|key|srcElement|mouse|menu|rightClick|parentWindow|xul|after|filter|before|original|prepend|abort|DXImageTransform|focusout|addClass|removeAttr|offsetHeight|offsetWidth|focusin|Microsoft|none|hide|String|toUpperCase|msie|zIndex|lineHeight|removeClass|toggleClass|td|fieldset|byTag|colgroup|option|innerText|show|removeAttribute|offsetParent|switch|relative|querySelector|pageXOffset|e2|scrollTo|pageYOffset|Firefox|prefix|createDocumentFragment|static|toString|pop|e1|method2|emit|undelegate|detach|trigger|Alpha|hover|cloneEvents|unbind|unlisten|empty|bind|listen|delegate'.split('|'),0,{})) +/*! + * ============================================================= + * Ender: open module JavaScript framework (https://ender.no.de) + * Build: ender build jeesh reqwest + * ============================================================= + */ + +/*! + * Ender: open module JavaScript framework (client-lib) + * copyright Dustin Diaz & Jacob Thornton 2011 (@ded @fat) + * http://ender.no.de + * License MIT + */ +!function(a){function d(a){var c=b[a]||window[a];if(!c)throw new Error("Requested module '"+a+"' has not been defined.");return c}function e(a,c){return b[a]=c}function f(a,b){for(var c in b)c!="noConflict"&&c!="_VERSION"&&(a[c]=b[c]);return a}function g(a,b,c){return h._select&&(typeof a=="string"||a.nodeName||a.length&&"item"in a||a==window)?(c=h._select(a,b),c.selector=a):c=isFinite(a.length)?a:[a],f(c,g)}function h(a,b){return g(a,b)}a.global=a;var b={},c=a.$;a.provide=e,a.require=d,f(h,{_VERSION:"0.3.4",fn:a.$&&a.$.fn||{},ender:function(a,b){f(b?g:h,a)},_select:function(a,b){return(b||document).querySelectorAll(a)}}),f(g,{forEach:function(a,b,c){for(c=0,l=this.length;c<l;++c)c in this&&a.call(b||this[c],this[c],c,this);return this},$:h}),h.noConflict=function(){return a.$=c,this},typeof module!="undefined"&&module.exports&&(module.exports=h),a.ender=a.$=a.ender||h}(this),!function(){var module={exports:{}},exports=module.exports; +/*! + * Reqwest! A general purpose XHR connection manager + * (c) Dustin Diaz 2011 + * https://github.com/ded/reqwest + * license MIT + */ +!function(a,b){typeof define=="function"?define(b):typeof module!="undefined"?module.exports=b():this[a]=b()}("reqwest",function(){function handleReadyState(a,b,c){return function(){a&&a[readyState]==4&&(twoHundo.test(a.status)?b(a):c(a))}}function setHeaders(a,b){var c=b.headers||{};c.Accept=c.Accept||"text/javascript, text/html, application/xml, text/xml, */*",b.crossOrigin||(c["X-Requested-With"]=c["X-Requested-With"]||"XMLHttpRequest"),c[contentType]=c[contentType]||"application/x-www-form-urlencoded";for(var d in c)c.hasOwnProperty(d)&&a.setRequestHeader(d,c[d])}function getCallbackName(a,b){var c=a.jsonpCallback||"callback";if(a.url.slice(-(c.length+2))==c+"=?"){var d="reqwest_"+b;return a.url=a.url.substr(0,a.url.length-1)+d,d}var e=new RegExp(c+"=([\\w]+)");return a.url.match(e)[1]}function generalCallback(a){lastValue=a}function getRequest(a,b,c){if(a.type!="jsonp"){var g=xhr(),h=(a.method||"GET").toUpperCase(),i=typeof a=="string"?a:a.url,j=a.processData!==!1&&a.data&&typeof a.data!="string"?reqwest.toQueryString(a.data):a.data||null;return h=="GET"&&j&&j!==""&&(i+=(/\?/.test(i)?"&":"?")+j)&&(j=null),g.open(h,i,!0),setHeaders(g,a),g.onreadystatechange=handleReadyState(g,b,c),a.before&&a.before(g),g.send(j),g}var d=doc.createElement("script"),e=0,f=uniqid++;win[getCallbackName(a,f)]=generalCallback,d.type="text/javascript",d.src=a.url,d.async=!0,typeof d.onreadystatechange!="undefined"&&(d.event="onclick",d.htmlFor=d.id="_reqwest_"+f),d.onload=d.onreadystatechange=function(){if(d[readyState]&&d[readyState]!=="complete"&&d[readyState]!=="loaded"||e)return!1;d.onload=d.onreadystatechange=null,d.onclick&&d.onclick(),a.success&&a.success(lastValue),lastValue=undefined,head.removeChild(d),e=1},head.appendChild(d)}function Reqwest(a,b){this.o=a,this.fn=b,init.apply(this,arguments)}function setType(a){return/\.json$/.test(a)?"json":/\.jsonp$/.test(a)?"jsonp":/\.js$/.test(a)?"js":/\.html?$/.test(a)?"html":/\.xml$/.test(a)?"xml":"js"}function init(o,fn){function complete(a){o.timeout&&clearTimeout(self.timeout),self.timeout=null,o.complete&&o.complete(a)}function success(resp){var r=resp.responseText;if(r)switch(type){case"json":try{resp=win.JSON?win.JSON.parse(r):eval("("+r+")")}catch(err){return error(resp,"Could not parse JSON in response",err)}break;case"js":resp=eval(r);break;case"html":resp=r}fn(resp),o.success&&o.success(resp),complete(resp)}function error(a,b,c){o.error&&o.error(a,b,c),complete(a)}this.url=typeof o=="string"?o:o.url,this.timeout=null;var type=o.type||setType(this.url),self=this;fn=fn||function(){},o.timeout&&(this.timeout=setTimeout(function(){self.abort()},o.timeout)),this.request=getRequest(o,success,error)}function reqwest(a,b){return new Reqwest(a,b)}function normalize(a){return a?a.replace(/\r?\n/g,"\r\n"):""}function serial(a,b){var c=a.name,d=a.tagName.toLowerCase(),e;if(a.disabled||!c)return;switch(d){case"input":if(!/reset|button|image|file/i.test(a.type)){var f=/checkbox/i.test(a.type),g=/radio/i.test(a.type),h=a.value;(!f&&!g||a.checked)&&b(c,normalize(f&&h===""?"on":h))}break;case"textarea":b(c,normalize(a.value));break;case"select":if(a.type.toLowerCase()==="select-one")e=a.selectedIndex<0?null:a.options[a.selectedIndex],e&&!e.disabled&&b(c,normalize(e.value||e.text));else for(var i=0;a.length&&i<a.length;i++)e=a.options[i],e.selected&&!e.disabled&&b(c,normalize(e.value||e.text))}}function eachFormElement(){var a=this,b=function(b,c){for(var d=0;d<c.length;d++){var e=b[byTag](c[d]);for(var f=0;f<e.length;f++)serial(e[f],a)}};for(var c=0;c<arguments.length;c++){var d=arguments[c];/input|select|textarea/i.test(d.tagName)&&serial(d,a),b(d,["input","select","textarea"])}}function serializeQueryString(){return reqwest.toQueryString(reqwest.serializeArray.apply(null,arguments))}function serializeHash(){var a={};return eachFormElement.apply(function(b,c){b in a?(a[b]&&!isArray(a[b])&&(a[b]=[a[b]]),a[b].push(c)):a[b]=c},arguments),a}var context=this,win=window,doc=document,old=context.reqwest,twoHundo=/^20\d$/,byTag="getElementsByTagName",readyState="readyState",contentType="Content-Type",head=doc[byTag]("head")[0],uniqid=0,lastValue,xhr="XMLHttpRequest"in win?function(){return new XMLHttpRequest}:function(){return new ActiveXObject("Microsoft.XMLHTTP")};Reqwest.prototype={abort:function(){this.request.abort()},retry:function(){init.call(this,this.o,this.fn)}};var isArray=typeof Array.isArray=="function"?Array.isArray:function(a){return Object.prototype.toString.call(a)=="[object Array]"};return reqwest.serializeArray=function(){var a=[];return eachFormElement.apply(function(b,c){a.push({name:b,value:c})},arguments),a},reqwest.serialize=function(){if(arguments.length===0)return"";var a,b,c=Array.prototype.slice.call(arguments,0);return a=c.pop(),a&&a.nodeType&&c.push(a)&&(a=null),a&&(a=a.type),a=="map"?b=serializeHash:a=="array"?b=reqwest.serializeArray:b=serializeQueryString,b.apply(null,c)},reqwest.toQueryString=function(a){var b="",c,d=encodeURIComponent,e=function(a,c){b+=d(a)+"="+d(c)+"&"};if(isArray(a))for(c=0;a&&c<a.length;c++)e(a[c].name,a[c].value);else for(var f in a){if(!Object.hasOwnProperty.call(a,f))continue;var g=a[f];if(isArray(g))for(c=0;c<g.length;c++)e(f,g[c]);else e(f,a[f])}return b.replace(/&$/,"").replace(/%20/g,"+")},reqwest.noConflict=function(){return context.reqwest=old,this},reqwest}),provide("reqwest",module.exports),!function(a){var b=require("reqwest"),c=function(a){return function(){var c=(this&&this.length>0?this:[]).concat(Array.prototype.slice.call(arguments,0));return b[a].apply(null,c)}},d=c("serialize"),e=c("serializeArray");a.ender({ajax:b,serialize:d,serializeArray:e,toQueryString:b.toQueryString}),a.ender({serialize:d,serializeArray:e},!0)}(ender)}(),!function(){var a={exports:{}},b=a.exports; +/*! + * bean.js - copyright Jacob Thornton 2011 + * https://github.com/fat/bean + * MIT License + * special thanks to: + * dean edwards: http://dean.edwards.name/ + * dperini: https://github.com/dperini/nwevents + * the entire mootools team: github.com/mootools/mootools-core + */ +!function(b,c){typeof define=="function"?define(c):typeof a!="undefined"?a.exports=c():this[b]=c()}("bean",function(){function F(a){var b=a.relatedTarget;return b?b!=this&&b.prefix!="xul"&&!/document/.test(this.toString())&&!p(this,b):b===null}var a=window,b=1,c={},d={},e=/over|out/,f=/[^\.]*(?=\..*)\.|.*/,g=/\..*/,h="addEventListener",i="attachEvent",j="removeEventListener",k="detachEvent",l=document||{},m=l.documentElement||{},n=m[h],o=n?h:i,p=function(a,b){var c=b.parentNode;while(c!==null){if(c==a)return!0;c=c.parentNode}},q=function(a,c){return a.__uid=c&&c+"::"+b++||a.__uid||b++},r=function(a){var b=q(a);return c[b]=c[b]||{}},s=n?function(a,b,c,d){a[d?h:j](b,c,!1)}:function(a,b,c,d,e){e&&d&&a["_on"+e]===null&&(a["_on"+e]=0),a[d?i:k]("on"+b,c)},t=function(b,c,d){return function(e){return e=D(e||((this.ownerDocument||this.document||this).parentWindow||a).event),c.apply(b,[e].concat(d))}},u=function(b,c,d,e,f){return function(g){if(e?e.apply(this,arguments):n?!0:g&&g.propertyName=="_on"+d||!g)g=g?D(g||((this.ownerDocument||this.document||this).parentWindow||a).event):null,c.apply(b,Array.prototype.slice.call(arguments,g?0:1).concat(f))}},v=function(a,b,c,e){var h=b.replace(g,""),i=r(a),j=i[h]||(i[h]={}),k=c,l=q(c,b.replace(f,""));if(j[l])return a;var m=G[h];m&&(c=m.condition?u(a,c,h,m.condition):c,h=m.base||h);var p=E[h];c=p?t(a,c,e):u(a,c,h,!1,e),p=n||p;if(h=="unload"){var v=c;c=function(){w(a,h,c)&&v()}}return a[o]&&s(a,p?h:"propertychange",c,!0,!p&&h),j[l]=c,c.__uid=l,c.__originalFn=k,h=="unload"?a:d[q(a)]=a},w=function(a,b,c){function l(b){c=j[k][b];if(!c)return;delete j[k][b];if(a[o]){k=G[k]?G[k].base:k;var d=n||E[k];s(a,d?k:"propertychange",c,!1,!d&&k)}}var d,e,h,i,j=r(a),k=b.replace(g,"");if(!j||!j[k])return a;e=b.replace(f,""),h=e?e.split("."):[c.__uid],l(e);for(i=h.length;i--;l(h[i]));return a},x=function(a,b,c){return function(d){var e=typeof a=="string"?c(a,this):a;for(var f=d.target;f&&f!=this;f=f.parentNode)for(var g=e.length;g--;)if(e[g]==f)return b.apply(f,arguments)}},y=function(a,b,c,d,e){if(typeof b=="object"&&!c)for(var f in b)b.hasOwnProperty(f)&&y(a,f,b[f]);else{var g=typeof c=="string",h=(g?c:b).split(" ");c=g?x(b,d,e):c;for(var i=h.length;i--;)v(a,h[i],c,Array.prototype.slice.call(arguments,g?4:3))}return a},z=function(a,b,c){var d,e,h,i,j,k=typeof b=="string",l=k&&b.replace(f,""),m=w,n=r(a);l=l&&l.split(".");if(k&&/\s/.test(b)){b=b.split(" "),j=b.length-1;while(z(a,b[j])&&j--);return a}i=k?b.replace(g,""):b;if(!n||l||k&&!n[i]){for(d in n)if(n.hasOwnProperty(d))for(j in n[d])for(e=l.length;e--;)n[d].hasOwnProperty(j)&&(new RegExp("^"+l[e]+"::\\d*(\\..*)?$")).test(j)&&m(a,[d,j].join("."));return a}if(typeof c=="function")m(a,i,c);else if(l)m(a,b);else{m=i?m:z,h=k&&i,i=i?c||n[i]||i:n;for(d in i)i.hasOwnProperty(d)&&(m(a,h||d,i[d]),delete i[d])}return a},A=function(a,b,c){var d,e,h,i,j=b.split(" ");for(h=j.length;h--;){b=j[h].replace(g,"");var k=E[b],l=j[h].replace(f,""),m=r(a)[b];if(l){l=l.split(".");for(e=l.length;e--;)for(i in m)m.hasOwnProperty(i)&&(new RegExp("^"+l[e]+"::\\d*(\\..*)?$")).test(i)&&m[i].apply(a,[!1].concat(c))}else if(!c&&a[o])B(k,b,a);else for(e in m)m.hasOwnProperty(e)&&m[e].apply(a,[!1].concat(c))}return a},B=n?function(b,c,d){evt=document.createEvent(b?"HTMLEvents":"UIEvents"),evt[b?"initEvent":"initUIEvent"](c,!0,!0,a,1),d.dispatchEvent(evt)}:function(a,b,c){a?c.fireEvent("on"+b,document.createEventObject()):c["_on"+b]++},C=function(a,b,c){var d=r(b),e,f,g=q(a);e=c?d[c]:d;for(f in e)e.hasOwnProperty(f)&&(c?y:C)(a,c||b,c?e[f].__originalFn:f);return a},D=function(a){var b={};if(!a)return b;var c=a.type,d=a.target||a.srcElement;b.preventDefault=D.preventDefault(a),b.stopPropagation=D.stopPropagation(a),b.target=d&&d.nodeType==3?d.parentNode:d;if(~c.indexOf("key"))b.keyCode=a.which||a.keyCode;else if(/click|mouse|menu/i.test(c)){b.rightClick=a.which==3||a.button==2,b.pos={x:0,y:0};if(a.pageX||a.pageY)b.clientX=a.pageX,b.clientY=a.pageY;else if(a.clientX||a.clientY)b.clientX=a.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,b.clientY=a.clientY+document.body.scrollTop+document.documentElement.scrollTop;e.test(c)&&(b.relatedTarget=a.relatedTarget||a[(c=="mouseover"?"from":"to")+"Element"])}for(var f in a)f in b||(b[f]=a[f]);return b};D.preventDefault=function(a){return function(){a.preventDefault?a.preventDefault():a.returnValue=!1}},D.stopPropagation=function(a){return function(){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0}};var E={click:1,dblclick:1,mouseup:1,mousedown:1,contextmenu:1,mousewheel:1,DOMMouseScroll:1,mouseover:1,mouseout:1,mousemove:1,selectstart:1,selectend:1,keydown:1,keypress:1,keyup:1,orientationchange:1,touchstart:1,touchmove:1,touchend:1,touchcancel:1,gesturestart:1,gesturechange:1,gestureend:1,focus:1,blur:1,change:1,reset:1,select:1,submit:1,load:1,unload:1,beforeunload:1,resize:1,move:1,DOMContentLoaded:1,readystatechange:1,error:1,abort:1,scroll:1},G={mouseenter:{base:"mouseover",condition:F},mouseleave:{base:"mouseout",condition:F},mousewheel:{base:/Firefox/.test(navigator.userAgent)?"DOMMouseScroll":"mousewheel"}},H={add:y,remove:z,clone:C,fire:A},I=function(a){var b=z(a).__uid;b&&(delete d[b],delete c[b])};return a[i]&&y(a,"unload",function(){for(var b in d)d.hasOwnProperty(b)&&I(d[b]);a.CollectGarbage&&CollectGarbage()}),H.noConflict=function(){return context.bean=old,this},H}),provide("bean",a.exports),!function(a){var b=require("bean"),c=function(c,d,e){var f=d?[d]:[];return function(){for(var e,g=0,h=this.length;g<h;g++)e=[this[g]].concat(f,Array.prototype.slice.call(arguments,0)),e.length==4&&e.push(a),!arguments.length&&c=="add"&&d&&(c="fire"),b[c].apply(this,e);return this}},d=c("add"),e=c("remove"),f=c("fire"),g={on:d,addListener:d,bind:d,listen:d,delegate:d,unbind:e,unlisten:e,removeListener:e,undelegate:e,emit:f,trigger:f,cloneEvents:c("clone"),hover:function(a,c,d){for(d=this.length;d--;)b.add.call(this,this[d],"mouseenter",a),b.add.call(this,this[d],"mouseleave",c);return this}},h,i=["blur","change","click","dblclick","error","focus","focusin","focusout","keydown","keypress","keyup","load","mousedown","mouseenter","mouseleave","mouseout","mouseover","mouseup","mousemove","resize","scroll","select","submit","unload"];for(h=i.length;h--;)g[i[h]]=c("add",i[h]);a.ender(g,!0)}(ender)}(),!function(){var a={exports:{}},b=a.exports; +/*! + * Bonzo: DOM Utility (c) Dustin Diaz 2011 + * https://github.com/ded/bonzo + * License MIT + */ +!function(b,c){typeof define=="function"?define(c):typeof a!="undefined"?a.exports=c():this[b]=c()}("bonzo",function(){function x(a){return new RegExp("(^|\\s+)"+a+"(\\s+|$)")}function y(a,b,c){for(var d=0,e=a.length;d<e;d++)b.call(c||a[d],a[d],d,a);return a}function z(a){return a.replace(/-(.)/g,function(a,b){return b.toUpperCase()})}function A(a){return a&&a.nodeName&&a.nodeType==1}function B(a,b,c,d){for(d=0,j=a.length;d<j;++d)if(b.call(c,a[d],d,a))return!0;return!1}function D(a,b,c){var d=0,g=b||this,h=[],i=f&&typeof a=="string"&&a.charAt(0)!="<"?f(a):a;return y(J(i),function(a){y(g,function(b){var f=!b[e]||b[e]&&!b[e][e]?function(){var a=b.cloneNode(!0);return g.$&&g.cloneEvents&&g.$(a).cloneEvents(b),a}():b;c(a,f),h[d]=f,d++})},this),y(h,function(a,b){g[b]=a}),g.length=d,g}function E(a,b,c){var d=N(a),e=d.css("position"),f=d.offset(),g="relative",h=e==g,i=[parseInt(d.css("left"),10),parseInt(d.css("top"),10)];e=="static"&&(d.css("position",g),e=g),isNaN(i[0])&&(i[0]=h?0:a.offsetLeft),isNaN(i[1])&&(i[1]=h?0:a.offsetTop),b!=null&&(a.style.left=b-f.left+i[0]+q),c!=null&&(a.style.top=c-f.top+i[1]+q)}function F(a,b){return x(b).test(a.className)}function G(a,b){a.className=w(a.className+" "+b)}function H(a,b){a.className=w(a.className.replace(x(b)," "))}function I(a){this.length=0;if(a){a=typeof a!="string"&&!a.nodeType&&typeof a.length!="undefined"?a:[a],this.length=a.length;for(var b=0;b<a.length;b++)this[b]=a[b]}}function J(a){return typeof a=="string"?N.create(a):A(a)?[a]:a}function K(a,c,d){var e=this[0];return a==null&&c==null?(L(e)?M():{x:e.scrollLeft,y:e.scrollTop})[d]:(L(e)?b.scrollTo(a,c):(a!=null&&(e.scrollLeft=a),c!=null&&(e.scrollTop=c)),this)}function L(a){return a===b||/^(?:body|html)$/i.test(a.tagName)}function M(){return{x:b.pageXOffset||d.scrollLeft,y:b.pageYOffset||d.scrollTop}}function N(a,b){return new I(a,b)}var a=this,b=window,c=b.document,d=c.documentElement,e="parentNode",f=null,g=/^checked|value|selected$/,h=/select|fieldset|table|tbody|tfoot|td|tr|colgroup/i,i="table",k={thead:i,tbody:i,tfoot:i,tr:"tbody",th:"tr",td:"tr",fieldset:"form",option:"select"},l=/^checked|selected$/,m=/msie/i.test(navigator.userAgent),n=[],o=0,p=/^-?[\d\.]+$/,q="px",r="setAttribute",s="getAttribute",t=/(^\s*|\s*$)/g,u={lineHeight:1,zoom:1,zIndex:1,opacity:1},v=function(){var a=["webkitTransform","MozTransform","OTransform","msTransform","Transform"],b;for(b=0;b<a.length;b++)if(a[b]in c.createElement("a").style)return a[b]}(),w=String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(t,"")},C=c.defaultView&&c.defaultView.getComputedStyle?function(a,b){b=b=="transform"?v:b,b=b=="transform-origin"?v+"Origin":b;var d=null;b=="float"&&(b="cssFloat");var e=c.defaultView.getComputedStyle(a,"");return e&&(d=e[z(b)]),a.style[b]||d}:m&&d.currentStyle?function(a,b){b=z(b),b=b=="float"?"styleFloat":b;if(b=="opacity"){var c=100;try{c=a.filters["DXImageTransform.Microsoft.Alpha"].opacity}catch(d){try{c=a.filters("alpha").opacity}catch(e){}}return c/100}var f=a.currentStyle?a.currentStyle[b]:null;return a.style[b]||f}:function(a,b){return a.style[z(b)]};I.prototype={get:function(a){return this[a]},each:function(a,b){return y(this,a,b)},map:function(a,b){var c=[],d,e;for(e=0;e<this.length;e++)d=a.call(this,this[e],e),b?b(d)&&c.push(d):c.push(d);return c},first:function(){return N(this[0])},last:function(){return N(this[this.length-1])},html:function(a,b){function f(b){while(b.firstChild)b.removeChild(b.firstChild);y(J(a),function(a){b.appendChild(a)})}var c=b?d.textContent===null?"innerText":"textContent":"innerHTML",e;return typeof a!="undefined"?this.each(function(b){(e=b.tagName.match(h))?f(b,e[0]):b[c]=a}):this[0]?this[0][c]:""},text:function(a){return this.html(a,1)},addClass:function(a){return this.each(function(b){F(b,a)||G(b,a)})},removeClass:function(a){return this.each(function(b){F(b,a)&&H(b,a)})},hasClass:function(a){return B(this,function(b){return F(b,a)})},toggleClass:function(a,b){return this.each(function(c){typeof b!="undefined"?b?G(c,a):H(c,a):F(c,a)?H(c,a):G(c,a)})},show:function(a){return this.each(function(b){b.style.display=a||""})},hide:function(a){return this.each(function(a){a.style.display="none"})},append:function(a){return this.each(function(b){y(J(a),function(a){b.appendChild(a)})})},prepend:function(a){return this.each(function(b){var c=b.firstChild;y(J(a),function(a){b.insertBefore(a,c)})})},appendTo:function(a,b){return D.call(this,a,b,function(a,b){a.appendChild(b)})},prependTo:function(a,b){return D.call(this,a,b,function(a,b){a.insertBefore(b,a.firstChild)})},next:function(){return this.related("nextSibling")},previous:function(){return this.related("previousSibling")},related:function(a){return this.map(function(b){b=b[a];while(b&&b.nodeType!==1)b=b[a];return b||0},function(a){return a})},before:function(a){return this.each(function(b){y(N.create(a),function(a){b[e].insertBefore(a,b)})})},after:function(a){return this.each(function(b){y(N.create(a),function(a){b[e].insertBefore(a,b.nextSibling)})})},insertBefore:function(a,b){return D.call(this,a,b,function(a,b){a[e].insertBefore(b,a)})},insertAfter:function(a,b){return D.call(this,a,b,function(a,b){var c=a.nextSibling;c?a[e].insertBefore(b,c):a[e].appendChild(b)})},replaceWith:function(a){return this.each(function(b){b.parentNode.replaceChild(N.create(a)[0],b)})},css:function(a,d,e){function g(a,b,c){for(var d in f)f.hasOwnProperty(d)&&(c=f[d],(b=z(d))&&p.test(c)&&!(b in u)&&(c+=q),b=b=="transform"?v:b,b=b=="transformOrigin"?v+"Origin":b,a.style[b]=c)}if(d===undefined&&typeof a=="string")return d=this[0],d?d==c||d==b?(e=d==c?N.doc():N.viewport(),a=="width"?e.width:a=="height"?e.height:""):C(d,a):null;var f=a;typeof a=="string"&&(f={},f[a]=d),m&&f.opacity&&(f.filter="alpha(opacity="+f.opacity*100+")",f.zoom=a.zoom||1,delete f.opacity);if(d=f["float"])m?f.styleFloat=d:f.cssFloat=d,delete f["float"];return this.each(g)},offset:function(a,b){if(typeof a=="number"||typeof b=="number")return this.each(function(c){E(c,a,b)});var c=this[0],d=c.offsetWidth,e=c.offsetHeight,f=c.offsetTop,g=c.offsetLeft;while(c=c.offsetParent)f+=c.offsetTop,g+=c.offsetLeft;return{top:f,left:g,height:e,width:d}},attr:function(a,b){var c=this[0];if(typeof a=="string"||a instanceof String)return typeof b=="undefined"?g.test(a)?l.test(a)&&typeof c[a]=="string"?!0:c[a]:c[s](a):this.each(function(c){g.test(a)?c[a]=b:c[r](a,b)});for(var d in a)a.hasOwnProperty(d)&&this.attr(d,a[d]);return this},val:function(a){return typeof a=="string"?this.attr("value",a):this[0].value},removeAttr:function(a){return this.each(function(b){l.test(a)?b[a]=!1:b.removeAttribute(a)})},data:function(a,b){var c=this[0];if(typeof b=="undefined"){c[s]("data-node-uid")||c[r]("data-node-uid",++o);var d=c[s]("data-node-uid");return n[d]||(n[d]={}),n[d][a]}return this.each(function(c){c[s]("data-node-uid")||c[r]("data-node-uid",++o);var d=c[s]("data-node-uid"),e=n[d]||(n[d]={});e[a]=b})},remove:function(){return this.each(function(a){a[e]&&a[e].removeChild(a)})},empty:function(){return this.each(function(a){while(a.firstChild)a.removeChild(a.firstChild)})},detach:function(){return this.map(function(a){return a[e].removeChild(a)})},scrollTop:function(a){return K.call(this,null,a,"y")},scrollLeft:function(a){return K.call(this,a,null,"x")},toggle:function(a){return this.each(function(a){a.style.display=a.offsetWidth||a.offsetHeight?"none":"block"}),a&&a(),this}},N.setQueryEngine=function(a){f=a,delete N.setQueryEngine},N.aug=function(a,b){for(var c in a)a.hasOwnProperty(c)&&((b||I.prototype)[c]=a[c])},N.create=function(a){return typeof a=="string"?function(){var b=/^<([^\s>]+)/.exec(a),d=c.createElement(b&&k[b[1].toLowerCase()]||"div"),e=[];d.innerHTML=a;var f=d.childNodes;d=d.firstChild,e.push(d);while(d=d.nextSibling)d.nodeType==1&&e.push(d);return e}():A(a)?[a.cloneNode(!0)]:[]},N.doc=function(){var a=this.viewport();return{width:Math.max(c.body.scrollWidth,d.scrollWidth,a.width),height:Math.max(c.body.scrollHeight,d.scrollHeight,a.height)}},N.firstChild=function(a){for(var b=a.childNodes,c=0,d=b&&b.length||0,e;c<d;c++)b[c].nodeType===1&&(e=b[d=c]);return e},N.viewport=function(){return{width:m?d.clientWidth:self.innerWidth,height:m?d.clientHeight:self.innerHeight}},N.isAncestor="compareDocumentPosition"in d?function(a,b){return(a.compareDocumentPosition(b)&16)==16}:"contains"in d?function(a,b){return a!==b&&a.contains(b)}:function(a,b){while(b=b[e])if(b===a)return!0;return!1};var O=a.bonzo;return N.noConflict=function(){return a.bonzo=O,this},N}),provide("bonzo",a.exports),!function(a){function c(a,b){for(var c=0;c<a.length;c++)if(a[c]===b)return c;return-1}function d(a){var b=[],c,d;e:for(c=0;c<a.length;c++){for(d=0;d<b.length;d++)if(b[d]==a[c])continue e;b[b.length]=a[c]}return b}function e(a,b,c){return a?b.css(c,a):function(a){return a=parseInt(b.css(c),10),isNaN(a)?b[0]["offset"+c.replace(/^\w/,function(a){return a.toUpperCase()})]:a}()}var b=require("bonzo");b.setQueryEngine(a),a.ender(b),a.ender(b(),!0),a.ender({create:function(c){return a(b.create(c))}}),a.id=function(b){return a([document.getElementById(b)])},a.ender({parents:function(b,e){var f=a(b),g,h,i,j=[];for(g=0,h=this.length;g<h;g++){i=this[g];while(i=i.parentNode)if(~c(f,i)){j.push(i);if(e)break}}return a(d(j))},closest:function(a){return this.parents(a,!0)},first:function(){return a(this[0])},last:function(){return a(this[this.length-1])},next:function(){return a(b(this).next())},previous:function(){return a(b(this).previous())},appendTo:function(a){return b(this.selector).appendTo(a,this)},prependTo:function(a){return b(this.selector).prependTo(a,this)},insertAfter:function(a){return b(this.selector).insertAfter(a,this)},insertBefore:function(a){return b(this.selector).insertBefore(a,this)},siblings:function(){var b,c,d,e=[];for(b=0,c=this.length;b<c;b++){d=this[b];while(d=d.previousSibling)d.nodeType==1&&e.push(d);d=this[b];while(d=d.nextSibling)d.nodeType==1&&e.push(d)}return a(e)},children:function(){var c,e,f=[];for(c=0,l=this.length;c<l;c++){if(!(e=b.firstChild(this[c])))continue;f.push(e);while(e=e.nextSibling)e.nodeType==1&&f.push(e)}return a(d(f))},height:function(a){return e(a,this,"height")},width:function(a){return e(a,this,"width")}},!0)}(ender)}(),!function(){var a={exports:{}},b=a.exports;!function(b,c){typeof define=="function"?define(c):typeof a!="undefined"?a.exports=c():this[b]=this.domReady=c()}("domready",function(a){function l(a){k=1;while(a=b.shift())a()}var b=[],c,d=!1,e=document,f=e.documentElement,g=f.doScroll,h="DOMContentLoaded",i="addEventListener",j="onreadystatechange",k=/^loade|c/.test(e.readyState);return e[i]&&e[i](h,c=function(){e.removeEventListener(h,c,d),l()},d),g&&e.attachEvent(j,c=function(){/^c/.test(e.readyState)&&(e.detachEvent(j,c),l())}),a=g?function(c){self!=top?k?c():b.push(c):function(){try{f.doScroll("left")}catch(b){return setTimeout(function(){a(c)},50)}c()}()}:function(a){k?a():b.push(a)}}),provide("domready",a.exports),!function(a){var b=require("domready");a.ender({domReady:b}),a.ender({ready:function(a){return b(a),this}},!0)}(ender)}(),!function(){var a={exports:{}},b=a.exports; +/*! + * Qwery - A Blazing Fast query selector engine + * https://github.com/ded/qwery + * copyright Dustin Diaz & Jacob Thornton 2011 + * MIT License + */ +!function(b,c){typeof define=="function"?define(c):typeof a!="undefined"?a.exports=c():this[b]=c()}("qwery",function(){function M(){this.c={}}function R(a){l=[];for(e=0,h=a.length;e<h;e++)$(a[e])?l=l.concat(a[e]):l.push(a[e]);return l}function S(a){while(a=a.previousSibling)if(a.nodeType==1)break;return a}function T(a){return a.match(K)}function U(a,b,c,d,f,g,h,i,k,l,m){var n,o,p;if(b&&this.tagName.toLowerCase()!==b)return!1;if(c&&(n=c.match(v))&&n[1]!==this.id)return!1;if(c&&(q=c.match(w)))for(e=q.length;e--;){o=q[e].slice(1);if(!(N.g(o)||N.s(o,new RegExp("(^|\\s+)"+o+"(\\s+|$)"))).test(this.className))return!1}if(k&&ba.pseudos[k]&&!ba.pseudos[k](this,m))return!1;if(d&&!h){j=this.attributes;for(p in j)if(Object.prototype.hasOwnProperty.call(j,p)&&(j[p].name||p)==f)return this}return d&&!W(g,this.getAttribute(f)||"",h)?!1:this}function V(a){return O.g(a)||O.s(a,a.replace(E,"\\$1"))}function W(a,b,c){switch(a){case"=":return b==c;case"^=":return b.match(P.g("^="+c)||P.s("^="+c,new RegExp("^"+V(c))));case"$=":return b.match(P.g("$="+c)||P.s("$="+c,new RegExp(V(c)+"$")));case"*=":return b.match(P.g(c)||P.s(c,new RegExp(V(c))));case"~=":return b.match(P.g("~="+c)||P.s("~="+c,new RegExp("(?:^|\\s+)"+V(c)+"(?:\\s+|$)")));case"|=":return b.match(P.g("|="+c)||P.s("|="+c,new RegExp("^"+V(c)+"(-|$)")))}return 0}function X(a){var c=[],d=[],e,f=0,g,h,i,j,k,l,m,n,o,q,r,s=Q.g(a)||Q.s(a,a.split(J)),t=a.match(I),u;s=s.slice(0);if(!s.length)return c;k=s.pop(),n=s.length&&(i=s[s.length-1].match(x))?b.getElementById(i[1]):b;if(!n)return c;o=T(k),m=t&&/^[+~]$/.test(t[t.length-1])?function(a){while(n=n.nextSibling)n.nodeType==1&&(o[1]?o[1]==n.tagName.toLowerCase():1)&&a.push(n);return a}([]):n.getElementsByTagName(o[1]||"*");for(e=0,h=m.length;e<h;e++)if(q=U.apply(m[e],o))c[f++]=q;if(!s.length)return c;for(f=0,h=c.length,g=0;f<h;f++){j=c[f];for(e=s.length;e--;)while(j=L[t[e]](j,c[f]))if(p=U.apply(j,T(s[e])))break;p&&(d[g++]=c[f])}return d}function Y(a){return a&&a.nodeType&&(a.nodeType==1||a.nodeType==9)}function Z(a){var b=[],c,d;e:for(c=0;c<a.length;c++){for(d=0;d<b.length;d++)if(b[d]==a[c])continue e;b[b.length]=a[c]}return b}function $(a){return typeof a=="object"&&isFinite(a.length)}function _(a){return a?typeof a=="string"?ba(a)[0]:$(a)?a[0]:a:b}function ba(a,c){var d=_(c);return!d||!a?[]:a===window||Y(a)?!c||a!==window&&Y(d)&&bb(a,d)?[a]:[]:a&&$(a)?R(a):(i=a.match(x))?(n=b.getElementById(i[1]))?[n]:[]:(i=a.match(z))?R(d.getElementsByTagName(i[1])):bd(a,d)}var a=this,b=document,c=a.qwery,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u=b.documentElement,v=/#([\w\-]+)/,w=/\.[\w\-]+/g,x=/^#([\w\-]+$)/,y=/^\.([\w\-]+)$/,z=/^([\w\-]+)$/,A=/^([\w]+)?\.([\w\-]+)$/,B=/\s*([\s\+\~>])\s*/g,C=/[\s\>\+\~]/,D=/(?![\s\w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^'"]*\]|[\s\w\+\-]*\))/,E=/([.*+?\^=!:${}()|\[\]\/\\])/g,F=/^([a-z0-9]+)?(?:([\.\#]+[\w\-\.#]+)?)/,G=/\[([\w\-]+)(?:([\|\^\$\*\~]?\=)['"]?([ \w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^]+)["']?)?\]/,H=/:([\w\-]+)(\(['"]?([\s\w\+\-]+)['"]?\))?/,I=new RegExp("("+C.source+")"+D.source,"g"),J=new RegExp(C.source+D.source),K=new RegExp(F.source+"("+G.source+")?"+"("+H.source+")?"),L={" ":function(a){return a&&a!==u&&a.parentNode},">":function(a,b){return a&&a.parentNode==b.parentNode&&a.parentNode},"~":function(a){return a&&a.previousSibling},"+":function(a,b,c,d){return a?(c=S(a),d=S(b),c&&d&&c==d&&c):!1}};M.prototype={g:function(a){return this.c[a]||undefined},s:function(a,b){return this.c[a]=b,b}};var N=new M,O=new M,P=new M,Q=new M,bb="compareDocumentPosition"in u?function(a,b){return(b.compareDocumentPosition(a)&16)==16}:"contains"in u?function(a,c){return c=c==b||c==window?u:c,c!==a&&c.contains(a)}:function(a,b){while(a=a.parentNode)if(a===b)return 1;return 0},bc=function(){if(!b.querySelector||!b.querySelectorAll)return!1;try{return b.querySelectorAll(":nth-of-type(1)").length}catch(a){return!1}}(),bd=bc?function(a,c){return b.getElementsByClassName&&(i=a.match(y))?R(c.getElementsByClassName(i[1])):R(c.querySelectorAll(a))}:function(a,c){a=a.replace(B,"$1");var d=[],e,g,j=[],k;if(i=a.match(A)){s=c.getElementsByTagName(i[1]||"*"),l=N.g(i[2])||N.s(i[2],new RegExp("(^|\\s+)"+i[2]+"(\\s+|$)"));for(k=0,h=s.length,f=0;k<h;k++)l.test(s[k].className)&&(d[f++]=s[k]);return d}for(k=0,s=a.split(","),h=s.length;k<h;k++)j[k]=X(s[k]);for(k=0,h=j.length;k<h&&(g=j[k]);k++){var m=g;if(c!==b){m=[];for(f=0,i=g.length;f<i&&(e=g[f]);f++)bb(e,c)&&m.push(e)}d=d.concat(m)}return Z(d)};return ba.uniq=Z,ba.pseudos={},ba.noConflict=function(){return a.qwery=c,this},ba}),provide("qwery",a.exports),!function(a,b){function f(b,c){var d=/^\s*<([^\s>]+)\s*/.exec(b)[1],f=(c||a).createElement(e[d]||"div"),g=[];f.innerHTML=b;var h=f.childNodes;f=f.firstChild,f.nodeType==1&&g.push(f);while(f=f.nextSibling)f.nodeType==1&&g.push(f);return g}var c=require("qwery"),d="table",e={thead:d,tbody:d,tfoot:d,tr:"tbody",th:"tr",td:"tr",fieldset:"form",option:"select"};b._select=function(a,b){return/^\s*</.test(a)?f(a,b):c(a,b)},b.pseudos=c.pseudos,b.ender({find:function(a){var d=[],e,f,g,h,i;for(e=0,f=this.length;e<f;e++){i=c(a,this[e]);for(g=0,h=i.length;g<h;g++)d.push(i[g])}return b(c.uniq(d))},and:function(a){var c=b(a);for(var d=this.length,e=0,f=this.length+c.length;d<f;d++,e++)this[d]=c[e];return this}},!0)}(document,ender)}()
\ No newline at end of file diff --git a/.themes/classic/source/javascripts/github.js b/.themes/classic/source/javascripts/github.js index 623d493f..678775a9 100644 --- a/.themes/classic/source/javascripts/github.js +++ b/.themes/classic/source/javascripts/github.js @@ -1,43 +1,37 @@ -github = (function(){ - function render(target, repos){ - var i = 0, fragment = '', t = $(target)[0]; +var github = (function(){ + function render(target, repos){ + var i = 0, fragment = '', t = $(target)[0]; - for(i = 0; i < repos.length; i++) - fragment += '<li><a href="'+repos[i].url+'">'+repos[i].name+'</a><p>'+repos[i].description+'</p></li>'; - - t.innerHTML = fragment; + for(i = 0; i < repos.length; i++) { + fragment += '<li><a href="'+repos[i].url+'">'+repos[i].name+'</a><p>'+repos[i].description+'</p></li>'; } - return { - showRepos: function(options){ - var feed = new jXHR(); - feed.onerror = function (msg,url) { - $(options.target + ' li.loading').addClass('error').text("Error loading feed"); - } - feed.onreadystatechange = function(data){ - if (feed.readyState === 4) { - var repos = []; - var i; - for (i = 0; i < data.repositories.length; i++){ - if (options.skip_forks && data.repositories[i].fork) - continue; - repos.push(data.repositories[i]); - } - repos.sort(function(a, b){ - var a = new Date(a.pushed_at), - b = new Date(b.pushed_at); - - if (a.valueOf() == b.valueOf()) return 0; - return a.valueOf() > b.valueOf() ? -1 : 1; - }); + t.innerHTML = fragment; + } + return { + showRepos: function(options){ + $.ajax({ + url: "http://github.com/api/v2/json/repos/show/"+options.user+"?callback=?" + , type: 'jsonp' + , error: function (err) { $(options.target + ' li.loading').addClass('error').text("Error loading feed"); } + , success: function(data) { + var repos = []; + if (!data || !data.repositories) { return; } + for (var i = 0; i < data.repositories.length; i++) { + if (options.skip_forks && data.repositories[i].fork) { continue; } + repos.push(data.repositories[i]); + } + repos.sort(function(a, b) { + var aDate = new Date(a.pushed_at).valueOf(), + bDate = new Date(b.pushed_at).valueOf(); - if (options.count) - repos.splice(options.count); + if (aDate === bDate) { return 0; } + return aDate > bDate ? -1 : 1; + }); - render(options.target, repos) - } - }; - feed.open("GET","http://github.com/api/v2/json/repos/show/"+options.user+"?callback=?"); - feed.send(); + if (options.count) { repos.splice(options.count); } + render(options.target, repos); } - }; -})();
\ No newline at end of file + }); + } + }; +})(); diff --git a/.themes/classic/source/javascripts/octopress.js b/.themes/classic/source/javascripts/octopress.js index 5266ecb3..379e6630 100644 --- a/.themes/classic/source/javascripts/octopress.js +++ b/.themes/classic/source/javascripts/octopress.js @@ -1,38 +1,46 @@ -function getNav(){ - var mobileNav = $('nav[role=navigation] fieldset[role=site-search]').after('<fieldset role="mobile-nav"></fieldset>').next().append('<select></select>'); +function getNav() { + var mobileNav = $('nav[role=navigation] fieldset[role=search]').after('<fieldset class="mobile-nav"></fieldset>').next().append('<select></select>'); mobileNav.children('select').append('<option value="">Navigate…</option>'); - $($('ul[role=main-navigation] a')).each(function(link) { - mobileNav.children('select').append('<option value="'+link.href+'">• '+link.text+'</option>') + $('ul[role=main-navigation]').addClass('main-navigation'); + $('ul.main-navigation a').each(function(link) { + mobileNav.children('select').append('<option value="'+link.href+'">» '+link.text+'</option>'); }); - mobileNav.children('select').bind('change', function(event){ - if (event.target.value) window.location.href = event.target.value; + $('ul.subscription a').each(function(link) { + mobileNav.children('select').append('<option value="'+link.href+'">» '+link.text+'</option>'); + }); + mobileNav.children('select').bind('change', function(event) { + if (event.target.value) { window.location.href = event.target.value; } }); } + function addSidebarToggler() { - $('#content').append('<span class="toggle-sidebar"></span>'); - $('.toggle-sidebar').bind('click', function(e){ - e.preventDefault(); - if($('body').hasClass('collapse-sidebar')){ - $('body').removeClass('collapse-sidebar'); - } else { - $('body').addClass('collapse-sidebar'); - } - }); - sections = $('aside[role=sidebar] > section') - if(sections.length > 1){ + if(!$('body').hasClass('sidebar-footer')) { + $('#content').append('<span class="toggle-sidebar"></span>'); + $('.toggle-sidebar').bind('click', function(e) { + e.preventDefault(); + if ($('body').hasClass('collapse-sidebar')) { + $('body').removeClass('collapse-sidebar'); + } else { + $('body').addClass('collapse-sidebar'); + } + }); + } + var sections = $('aside.sidebar > section'); + if (sections.length > 1) { sections.each(function(section, index){ - if ((sections.length >= 3) && index % 3 == 0) { + if ((sections.length >= 3) && index % 3 === 0) { $(section).addClass("first"); } - count = ((index +1) % 2) ? "odd" : "even"; + var count = ((index +1) % 2) ? "odd" : "even"; $(section).addClass(count); }); } - if(sections.length >= 3){ $('aside[role=sidebar]').addClass('thirds') } + if (sections.length >= 3){ $('aside.sidebar').addClass('thirds'); } } + function testFeatures() { var features = ['maskImage']; - $(features).map(function(feature){ + $(features).map(function(feature) { if (Modernizr.testAllProps(feature)) { $('html').addClass(feature); } else { @@ -46,59 +54,69 @@ function testFeatures() { } } -function addCodeLineNumbers(){ - if (navigator.appName == 'Microsoft Internet Explorer') { return } - $('div.gist-highlight').each(function(code){ - var tableStart = '<table cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter">'; - var lineNumbers = '<pre class="line-numbers">'; - var tableMiddle = '</pre></td><td class="code" width="100%">'; - var tableEnd = '</td></tr></tbody></table>'; - var count = $('div.line', code).length; - for (i=1;i<=count; i++){ - lineNumbers += '<span class="line">'+i+'</span>\n'; +function addCodeLineNumbers() { + if (navigator.appName === 'Microsoft Internet Explorer') { return; } + $('div.gist-highlight').each(function(code) { + var tableStart = '<table><tbody><tr><td class="gutter">', + lineNumbers = '<pre class="line-numbers">', + tableMiddle = '</pre></td><td class="code">', + tableEnd = '</td></tr></tbody></table>', + count = $('.line', code).length; + for (var i=1;i<=count; i++) { + lineNumbers += '<span class="line-number">'+i+'</span>\n'; } - table = tableStart + lineNumbers + tableMiddle + '<pre>'+$('pre', code).html()+'</pre>' + tableEnd; + var table = tableStart + lineNumbers + tableMiddle + '<pre>'+$('pre', code).html()+'</pre>' + tableEnd; $(code).html(table); }); } function flashVideoFallback(){ var flashplayerlocation = "/assets/jwplayer/player.swf", - flashplayerskin = "/assets/jwplayer/glow/glow.xml"; + flashplayerskin = "/assets/jwplayer/glow/glow.xml"; $('video').each(function(video){ video = $(video); - if(!Modernizr.video.h264 && swfobject.getFlashPlayerVersion() || window.location.hash.indexOf("flash-test") != -1){ - video.children('source[src$=mp4]').first().map(function(source){; + if (!Modernizr.video.h264 && swfobject.getFlashPlayerVersion() || window.location.hash.indexOf("flash-test") !== -1){ + video.children('source[src$=mp4]').first().map(function(source){ var src = $(source).attr('src'), - id = 'video_'+Math.round(1 + Math.random()*(100000)), - width = video.attr('width'), - height = parseInt(video.attr('height')) + 30; - video.after('<div class="flash-video"><div><div id='+id+'>'); + id = 'video_'+Math.round(1 + Math.random()*(100000)), + width = video.attr('width'), + height = parseInt(video.attr('height'), 10) + 30; + video.after('<div class="flash-video"><div><div id='+id+'>'); swfobject.embedSWF(flashplayerlocation, id, width, height + 30, "9.0.0", { file : src, image : video.attr('poster'), skin : flashplayerskin } , - { movie : src, wmode : "opaque", allowfullscreen : "true" }); + { movie : src, wmode : "opaque", allowfullscreen : "true" } + ); }); video.remove(); } }); } -function wrapFlashVideos(){ - $('object').each(function(object){ +function wrapFlashVideos() { + $('object').each(function(object) { object = $(object); - if(object.children('param[name=movie]')){ + if ( $('param[name=movie]', object).length ) { var wrapper = object.before('<div class="flash-video"><div>').previous(); $(wrapper).children().append(object); } }); - $('iframe[src*=vimeo],iframe[src*=youtube]').each(function(iframe){ + $('iframe[src*=vimeo],iframe[src*=youtube]').each(function(iframe) { iframe = $(iframe); var wrapper = iframe.before('<div class="flash-video"><div>').previous(); $(wrapper).children().append(iframe); }); } -$.domReady(function(){ +function renderDeliciousLinks(items) { + var output = "<ul>"; + for (var i=0,l=items.length; i<l; i++) { + output += '<li><a href="' + items[i].u + '" title="Tags: ' + (items[i].t == "" ? "" : items[i].t.join(', ')) + '">' + items[i].d + '</a></li>'; + } + output += "</ul>"; + $('#delicious').html(output); +} + +$.domReady(function() { testFeatures(); wrapFlashVideos(); flashVideoFallback(); @@ -113,17 +131,17 @@ $.domReady(function(){ // Source url: https://gist.github.com/901295 (function(doc) { var addEvent = 'addEventListener', - type = 'gesturestart', - qsa = 'querySelectorAll', - scales = [1, 1], - meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : []; + type = 'gesturestart', + qsa = 'querySelectorAll', + scales = [1, 1], + meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : []; function fix() { meta.content = 'width=device-width,minimum-scale=' + scales[0] + ',maximum-scale=' + scales[1]; doc.removeEventListener(type, fix, true); } if ((meta = meta[meta.length - 1]) && addEvent in doc) { fix(); - scales = [.25, 1.6]; + scales = [0.25, 1.6]; doc[addEvent](type, fix, true); } }(document)); @@ -140,3 +158,4 @@ b=j.userAgent.toLowerCase(),d=j.platform.toLowerCase(),g=d?/win/.test(d):/win/.t 10),e[1]=parseInt(c.replace(/^.*\.(.*)\s.*$/,"$1"),10),e[2]=/[a-zA-Z]/.test(c)?parseInt(c.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}else if(typeof v.ActiveXObject!=l)try{var f=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");if(f&&(c=f.GetVariable("$version")))k=!0,c=c.split(" ")[1].split(","),e=[parseInt(c[0],10),parseInt(c[1],10),parseInt(c[2],10)]}catch(h){}return{w3:a,pv:e,wk:b,ie:k,win:g,mac:d}}();return{embedSWF:function(a,b,d,i,k,e,c,f,h){var j={success:!1,id:b};if(g.w3&&!(g.wk&&g.wk<312)&& a&&b&&d&&i&&k){d+="";i+="";var p={};if(f&&typeof f===o)for(var m in f)p[m]=f[m];p.data=a;p.width=d;p.height=i;a={};if(c&&typeof c===o)for(var n in c)a[n]=c[n];if(e&&typeof e===o)for(var r in e)typeof a.flashvars!=l?a.flashvars+="&"+r+"="+e[r]:a.flashvars=r+"="+e[r];if(t(k))b=s(p,a,b),j.success=!0,j.ref=b}h&&h(j)},ua:g,getFlashPlayerVersion:function(){return{major:g.pv[0],minor:g.pv[1],release:g.pv[2]}},hasFlashPlayerVersion:t,createSWF:function(a,b,d){if(g.w3)return s(a,b,d)},getQueryParamValue:function(a){var b= i.location.search||i.location.hash;if(b){/\?/.test(b)&&(b=b.split("?")[1]);if(a==null)return u(b);for(var b=b.split("&"),d=0;d<b.length;d++)if(b[d].substring(0,b[d].indexOf("="))==a)return u(b[d].substring(b[d].indexOf("=")+1))}return""}}}(); + diff --git a/.themes/classic/source/javascripts/twitter.js b/.themes/classic/source/javascripts/twitter.js index a4e85557..c9b7519d 100644 --- a/.themes/classic/source/javascripts/twitter.js +++ b/.themes/classic/source/javascripts/twitter.js @@ -1,82 +1,78 @@ // JSON-P Twitter fetcher for Octopress -// (c) Brandon Mathis // MIT Lisence -function getTwitterFeed(user, count, replies) { - var feed = new jXHR(); - - feed.onerror = function (msg,url) { - $('#tweets li.loading').addClass('error').text("Twitter's busted"); - } - feed.onreadystatechange = function(data){ - if (feed.readyState === 4) { - var tweets = new Array(); - var i = 0; - for (i in data){ - if(tweets.length < count){ - if(replies || data[i].in_reply_to_user_id == null){ - tweets.push(data[i]); - } - } - } - showTwitterFeed(tweets, user); - } - }; - feed.open("GET","http://twitter.com/statuses/user_timeline/"+user+".json?trim_user=true&count="+(parseInt(count)+60)+"&callback=?"); - feed.send(); -} - -function showTwitterFeed(tweets, twitter_user){ - var timeline = document.getElementById('tweets'); - timeline.innerHTML=''; - for (t in tweets){ - timeline.innerHTML+='<li>'+'<p>'+'<a href="http://twitter.com/'+twitter_user+'/status/'+tweets[t].id_str+'">'+prettyDate(tweets[t].created_at)+'</a>'+linkifyTweet(tweets[t].text.replace(/\n/g, '<br>'))+'</p>'+'</li>'; - } -} -function linkifyTweet(text){ - return text.replace(/(https?:\/\/)([\w\-:;?&=+.%#\/]+)/gi, '<a href="$1$2">$2</a>') - .replace(/(^|\W)@(\w+)/g, '$1<a href="http://twitter.com/$2">@$2</a>') - .replace(/(^|\W)#(\w+)/g, '$1<a href="http://search.twitter.com/search?q=%23$2">#$2</a>'); -} - - - -// jXHR.js (JSON-P XHR) | v0.1 (c) Kyle Simpson | MIT License | http://mulletxhr.com/ -// uncompressed version available in source/javascripts/libs/jXHR.js -(function(c){var b=c.setTimeout,d=c.document,a=0;c.jXHR=function(){var e,g,n,h,m=null;function l(){try{h.parentNode.removeChild(h)}catch(o){}}function k(){g=false;e="";l();h=null;i(0)}function f(p){try{m.onerror.call(m,p,e)}catch(o){throw new Error(p)}}function j(){if((this.readyState&&this.readyState!=="complete"&&this.readyState!=="loaded")||g){return}this.onload=this.onreadystatechange=null;g=true;if(m.readyState!==4){f("Script failed to load ["+e+"].")}l()}function i(o,p){p=p||[];m.readyState=o;if(typeof m.onreadystatechange==="function"){m.onreadystatechange.apply(m,p)}}m={onerror:null,onreadystatechange:null,readyState:0,open:function(p,o){k();internal_callback="cb"+(a++);(function(q){c.jXHR[q]=function(){try{i.call(m,4,arguments)}catch(r){m.readyState=-1;f("Script failed to run ["+e+"].")}c.jXHR[q]=null}})(internal_callback);e=o.replace(/=\?/,"=jXHR."+internal_callback);i(1)},send:function(){b(function(){h=d.createElement("script");h.setAttribute("type","text/javascript");h.onload=h.onreadystatechange=function(){j.call(h)};h.setAttribute("src",e);d.getElementsByTagName("head")[0].appendChild(h)},0);i(2)},setRequestHeader:function(){},getResponseHeader:function(){return""},getAllResponseHeaders:function(){return[]}};k();return m}})(window); - +// (c) Brandon Mathis // MIT License /* Sky Slavin, Ludopoli. MIT license. * based on JavaScript Pretty Date * Copyright (c) 2008 John Resig (jquery.com) * Licensed under the MIT license. */ - function prettyDate(time) { - if (navigator.appName == 'Microsoft Internet Explorer') { + if (navigator.appName === 'Microsoft Internet Explorer') { return "<span>∞</span>"; // because IE date parsing isn't fun. + } + var say = { + just_now: " now", + minute_ago: "1m", + minutes_ago: "m", + hour_ago: "1h", + hours_ago: "h", + yesterday: "1d", + days_ago: "d", + last_week: "1w", + weeks_ago: "w" }; - var say = {}; - say.just_now = " now", - say.minute_ago = "1m", - say.minutes_ago = "m", - say.hour_ago = "1h", - say.hours_ago = "h", - say.yesterday = "1d", - say.days_ago = "d", - say.weeks_ago = "w" - - var current_date = new Date(); - current_date_time = current_date.getTime(); - current_date_full = current_date_time + (1 * 60000); - var date = new Date(time); - var diff = ((current_date_full - date.getTime()) / 1000); - var day_diff = Math.floor(diff / 86400); + var current_date = new Date(), + current_date_time = current_date.getTime(), + current_date_full = current_date_time + (1 * 60000), + date = new Date(time), + diff = ((current_date_full - date.getTime()) / 1000), + day_diff = Math.floor(diff / 86400); - if (isNaN(day_diff) || day_diff < 0) return "<span>∞</span>"; + if (isNaN(day_diff) || day_diff < 0) { return "<span>∞</span>"; } - return day_diff == 0 && ( + return day_diff === 0 && ( diff < 60 && say.just_now || diff < 120 && say.minute_ago || diff < 3600 && Math.floor(diff / 60) + say.minutes_ago || diff < 7200 && say.hour_ago || diff < 86400 && Math.floor(diff / 3600) + say.hours_ago) || - day_diff == 1 && say.yesterday || + day_diff === 1 && say.yesterday || day_diff < 7 && day_diff + say.days_ago || + day_diff === 7 && say.last_week || day_diff > 7 && Math.ceil(day_diff / 7) + say.weeks_ago; } + +function linkifyTweet(text, url) { + // Linkify urls, usernames, hashtags + text = text.replace(/(https?:\/\/)([\w\-:;?&=+.%#\/]+)/gi, '<a href="$1$2">$2</a>') + .replace(/(^|\W)@(\w+)/g, '$1<a href="http://twitter.com/$2">@$2</a>') + .replace(/(^|\W)#(\w+)/g, '$1<a href="http://search.twitter.com/search?q=%23$2">#$2</a>'); + + // Use twitter's api to replace t.co shortened urls with expanded ones. + for (var u in url) { + if(url[u].expanded_url != null){ + var shortUrl = new RegExp(url[u].url, 'g'); + text = text.replace(shortUrl, url[u].expanded_url); + var shortUrl = new RegExp(">"+(url[u].url.replace(/https?:\/\//, '')), 'g'); + text = text.replace(shortUrl, ">"+url[u].display_url); + } + } + return text +} + +function showTwitterFeed(tweets, twitter_user) { + var timeline = document.getElementById('tweets'), + content = ''; + + for (var t in tweets) { + content += '<li>'+'<p>'+'<a href="http://twitter.com/'+twitter_user+'/status/'+tweets[t].id_str+'">'+prettyDate(tweets[t].created_at)+'</a>'+linkifyTweet(tweets[t].text.replace(/\n/g, '<br>'), tweets[t].entities.urls)+'</p>'+'</li>'; + } + timeline.innerHTML = content; +} + +function getTwitterFeed(user, count, replies) { + count = parseInt(count, 10); + $.ajax({ + url: "http://api.twitter.com/1/statuses/user_timeline/" + user + ".json?trim_user=true&count=" + (count + 20) + "&include_entities=1&exclude_replies=" + (replies ? "0" : "1") + "&callback=?" + , type: 'jsonp' + , error: function (err) { $('#tweets li.loading').addClass('error').text("Twitter's busted"); } + , success: function(data) { showTwitterFeed(data.slice(0, count), user); } + }) +} @@ -1,17 +1,18 @@ source "http://rubygems.org" group :development do - gem 'rake' - gem 'rack' - gem 'jekyll' - gem 'rdiscount' - gem 'pygments.rb' - gem 'RedCloth' - gem 'haml', '>= 3.1' - gem 'compass', '>= 0.11' - gem 'rubypants' - gem 'rb-fsevent' - gem 'stringex' + gem 'rake', '~> 0.9.2' + gem 'rack', '~> 1.4.1' + gem 'jekyll', '~> 0.11.2' + gem 'rdiscount', '~> 1.6.8' + gem 'pygments.rb', '~> 0.2.12' + gem 'RedCloth', '~> 4.2.9' + gem 'haml', '~> 3.1.6' + gem 'compass', '~> 0.12.1' + gem 'rubypants', '~> 0.2.0' + gem 'rb-fsevent', '~> 0.9' + gem 'stringex', '~> 1.4.0' + gem 'liquid', '~> 2.3.0' end -gem 'sinatra', '1.2.6' +gem 'sinatra', '~> 1.3.2' diff --git a/Gemfile.lock b/Gemfile.lock index 0ae80bc7..1c1bf8d5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,65 +1,69 @@ GEM remote: http://rubygems.org/ specs: - RedCloth (4.2.8) + RedCloth (4.2.9) albino (1.3.3) posix-spawn (>= 0.3.6) blankslate (2.1.2.4) - chunky_png (1.2.1) + chunky_png (1.2.5) classifier (1.3.3) fast-stemmer (>= 1.0.0) - compass (0.11.5) + compass (0.12.1) chunky_png (~> 1.2) fssm (>= 0.2.7) sass (~> 3.1) - directory_watcher (1.4.0) - fast-stemmer (1.0.0) - ffi (1.0.9) - fssm (0.2.7) - haml (3.1.2) - jekyll (0.11.0) - albino (>= 1.3.2) - classifier (>= 1.3.1) - directory_watcher (>= 1.1.1) - kramdown (>= 0.13.2) - liquid (>= 1.9.0) - maruku (>= 0.5.9) - kramdown (0.13.3) - liquid (2.2.2) + directory_watcher (1.4.1) + fast-stemmer (1.0.1) + ffi (1.0.11) + fssm (0.2.9) + haml (3.1.6) + jekyll (0.11.2) + albino (~> 1.3) + classifier (~> 1.3) + directory_watcher (~> 1.1) + kramdown (~> 0.13) + liquid (~> 2.3) + maruku (~> 0.5) + kramdown (0.13.6) + liquid (2.3.0) maruku (0.6.0) syntax (>= 1.0.0) posix-spawn (0.3.6) - pygments.rb (0.1.3) - rubypython (>= 0.5.1) - rack (1.3.2) - rake (0.9.2) - rb-fsevent (0.4.3.1) + pygments.rb (0.2.12) + rubypython (~> 0.5.3) + rack (1.4.1) + rack-protection (1.2.0) + rack + rake (0.9.2.2) + rb-fsevent (0.9.1) rdiscount (1.6.8) rubypants (0.2.0) - rubypython (0.5.1) + rubypython (0.5.3) blankslate (>= 2.1.2.3) ffi (~> 1.0.7) - sass (3.1.5) - sinatra (1.2.6) - rack (~> 1.1) - tilt (>= 1.2.2, < 2.0) - stringex (1.3.0) + sass (3.1.18) + sinatra (1.3.2) + rack (~> 1.3, >= 1.3.6) + rack-protection (~> 1.2) + tilt (~> 1.3, >= 1.3.3) + stringex (1.4.0) syntax (1.0.0) - tilt (1.3.2) + tilt (1.3.3) PLATFORMS ruby DEPENDENCIES - RedCloth - compass (>= 0.11) - haml (>= 3.1) - jekyll - pygments.rb - rack - rake - rb-fsevent - rdiscount - rubypants - sinatra (= 1.2.6) - stringex + RedCloth (~> 4.2.9) + compass (~> 0.12.1) + haml (~> 3.1.6) + jekyll (~> 0.11.2) + liquid (~> 2.3.0) + pygments.rb (~> 0.2.12) + rack (~> 1.4.1) + rake (~> 0.9.2) + rb-fsevent (~> 0.9) + rdiscount (~> 1.6.8) + rubypants (~> 0.2.0) + sinatra (~> 1.3.2) + stringex (~> 1.4.0) diff --git a/README.markdown b/README.markdown index 84f0e183..06ea4232 100644 --- a/README.markdown +++ b/README.markdown @@ -3,15 +3,22 @@ Octopress is [Jekyll](https://github.com/mojombo/jekyll) blogging at its finest. 1. **Octopress sports a clean responsive theme** written in semantic HTML5, focused on readability and friendliness toward mobile devices. -2. **Code blogging is easy and beautiful.** Embed code (with [Solarized](http://ethanschoonover.com/solarized) styling) in your posts from gists or from your filesystem. -3. **Third party integration is simple** with built-in support for Twitter, Pinboard, Delicious, Disqus Comments, and Google Analytics. +2. **Code blogging is easy and beautiful.** Embed code (with [Solarized](http://ethanschoonover.com/solarized) styling) in your posts from gists, jsFiddle or from your filesystem. +3. **Third party integration is simple** with built-in support for Twitter, Pinboard, Delicious, GitHub Repositories, Disqus Comments and Google Analytics. 4. **It's easy to use.** A collection of rake tasks simplifies development and makes deploying a cinch. -5. **Ships with great plugins** some original and others from the Jekyll community — tested and improved. +5. **Ships with great plug-ins** some original and others from the Jekyll community — tested and improved. + ## Documentation Check out [Octopress.org](http://octopress.org/docs) for guides and documentation. + +## Contributing + +We love to see people contributing to Octopress, whether it's a bug report, feature suggestion or a pull request. At the moment, we try to keep the core slick and lean, focusing on basic blogging needs, so some of your suggestions might not find their way into Octopress. For those ideas, we started a [list of 3rd party plug-ins](https://github.com/imathis/octopress/wiki/3rd-party-plugins), where you can link your own Octopress plug-in repositories. For the future, we're thinking about ways to easier add them them into our main releases. + + ## License (The MIT License) @@ -23,6 +30,7 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #### If you want to be awesome. - Proudly display the 'Powered by Octopress' credit in the footer. -- Add your site to the wiki so we can watch the community grow. +- Add your site to the Wiki so we can watch the community grow. @@ -5,7 +5,9 @@ require "stringex" ## -- Rsync Deploy config -- ## # Be sure your public key is listed in your server's ~/.ssh/authorized_keys file ssh_user = "user@domain.com" +ssh_port = "22" document_root = "~/website.com/" +rsync_delete = true deploy_default = "rsync" # This will be configured for you when you run config_deploy @@ -49,6 +51,7 @@ desc "Generate jekyll site" task :generate do raise "### You haven't set anything up yet. First run `rake install` to set up an Octopress theme." unless File.directory?(source_dir) puts "## Generating Site with Jekyll" + system "compass compile --css-dir #{source_dir}/stylesheets" system "jekyll" end @@ -56,7 +59,8 @@ desc "Watch the site and regenerate when it changes" task :watch do raise "### You haven't set anything up yet. First run `rake install` to set up an Octopress theme." unless File.directory?(source_dir) puts "Starting to watch source with Jekyll and Compass." - jekyllPid = Process.spawn("jekyll --auto") + system "compass compile --css-dir #{source_dir}/stylesheets" unless File.exist?("#{source_dir}/stylesheets/screen.css") + jekyllPid = Process.spawn({"OCTOPRESS_ENV"=>"preview"}, "jekyll --auto") compassPid = Process.spawn("compass watch") trap("INT") { @@ -71,7 +75,8 @@ desc "preview the site in a web browser" task :preview do raise "### You haven't set anything up yet. First run `rake install` to set up an Octopress theme." unless File.directory?(source_dir) puts "Starting to watch source with Jekyll and Compass. Starting Rack on port #{server_port}" - jekyllPid = Process.spawn("jekyll --auto") + system "compass compile --css-dir #{source_dir}/stylesheets" unless File.exist?("#{source_dir}/stylesheets/screen.css") + jekyllPid = Process.spawn({"OCTOPRESS_ENV"=>"preview"}, "jekyll --auto") compassPid = Process.spawn("compass watch") rackupPid = Process.spawn("rackup --port #{server_port}") @@ -87,7 +92,6 @@ end desc "Begin a new post in #{source_dir}/#{posts_dir}" task :new_post, :title do |t, args| raise "### You haven't set anything up yet. First run `rake install` to set up an Octopress theme." unless File.directory?(source_dir) - require './plugins/titlecase.rb' mkdir_p "#{source_dir}/#{posts_dir}" args.with_defaults(:title => 'new-post') title = args.title @@ -97,10 +101,9 @@ task :new_post, :title do |t, args| end puts "Creating new post: #{filename}" open(filename, 'w') do |post| - system "mkdir -p #{source_dir}/#{posts_dir}/"; post.puts "---" post.puts "layout: post" - post.puts "title: \"#{title.gsub(/&/,'&').titlecase}\"" + post.puts "title: \"#{title.gsub(/&/,'&')}\"" post.puts "date: #{Time.now.strftime('%Y-%m-%d %H:%M')}" post.puts "comments: true" post.puts "categories: " @@ -112,16 +115,22 @@ end desc "Create a new page in #{source_dir}/(filename)/index.#{new_page_ext}" task :new_page, :filename do |t, args| raise "### You haven't set anything up yet. First run `rake install` to set up an Octopress theme." unless File.directory?(source_dir) - require './plugins/titlecase.rb' args.with_defaults(:filename => 'new-page') - page_dir = source_dir - if args.filename =~ /(^.+\/)?([\w_-]+)(\.)?(.+)?/ - page_dir += $4 ? "/#{$1}" : "/#{$1}#{$2}/" - name = $4 ? $2 : "index" - extension = $4 || "#{new_page_ext}" - filename = "#{name}.#{extension}" + page_dir = [source_dir] + if args.filename.downcase =~ /(^.+\/)?(.+)/ + filename, dot, extension = $2.rpartition('.').reject(&:empty?) # Get filename and extension + title = filename + page_dir.concat($1.downcase.sub(/^\//, '').split('/')) unless $1.nil? # Add path to page_dir Array + if extension.nil? + page_dir << filename + filename = "index" + end + extension ||= new_page_ext + page_dir = page_dir.map! { |d| d = d.to_url }.join('/') # Sanitize path + filename = filename.downcase.to_url + mkdir_p page_dir - file = page_dir + filename + file = "#{page_dir}/#{filename}.#{extension}" if File.exist?(file) abort("rake aborted!") if ask("#{file} already exists. Do you want to overwrite?", ['y', 'n']) == 'n' end @@ -129,7 +138,7 @@ task :new_page, :filename do |t, args| open(file, 'w') do |page| page.puts "---" page.puts "layout: page" - page.puts "title: \"#{$2.gsub(/[-_]/, ' ').titlecase}\"" + page.puts "title: \"#{title}\"" page.puts "date: #{Time.now.strftime('%Y-%m-%d %H:%M')}" page.puts "comments: true" page.puts "sharing: true" @@ -156,9 +165,9 @@ task :integrate do FileUtils.mv Dir.glob("#{source_dir}/#{stash_dir}/*.*"), "#{source_dir}/#{posts_dir}/" end -desc "Clean out caches: _code_cache, _gist_cache, .sass-cache" +desc "Clean out caches: .pygments-cache, .gist-cache, .sass-cache" task :clean do - rm_rf ["_code_cache/**", "_gist_cache/**", ".sass-cache/**", "source/stylesheets/screen.css"] + rm_rf [".pygments-cache/**", ".gist-cache/**", ".sass-cache/**", "source/stylesheets/screen.css"] end desc "Move sass to sass.old, install sass theme updates, replace sass/custom with sass.old/custom" @@ -182,12 +191,14 @@ task :update_source, :theme do |t, args| puts "## Removed existing #{source_dir}.old directory" rm_r "#{source_dir}.old", :secure=>true end + mkdir "#{source_dir}.old" cp_r "#{source_dir}/.", "#{source_dir}.old" puts "## Copied #{source_dir} into #{source_dir}.old/" cp_r "#{themes_dir}/"+theme+"/source/.", source_dir, :remove_destination=>true cp_r "#{source_dir}.old/_includes/custom/.", "#{source_dir}/_includes/custom/", :remove_destination=>true + cp "#{source_dir}.old/favicon.png", source_dir mv "#{source_dir}/index.html", "#{blog_index_dir}", :force=>true if blog_index_dir != source_dir - cp "#{source_dir}.old/index.html", source_dir if blog_index_dir != source_dir + cp "#{source_dir}.old/index.html", source_dir if blog_index_dir != source_dir && File.exists?("#{source_dir}.old/index.html") puts "## Updated #{source_dir} ##" end @@ -197,44 +208,53 @@ end desc "Default deploy task" task :deploy do - [:copydot, "#{deploy_default}"].each { |t| Rake::Task[t].execute } + # Check if preview posts exist, which should not be published + if File.exists?(".preview-mode") + puts "## Found posts in preview mode, regenerating files ..." + File.delete(".preview-mode") + Rake::Task[:generate].execute + end + + Rake::Task[:copydot].invoke(source_dir, public_dir) + Rake::Task["#{deploy_default}"].execute end desc "Generate website and deploy" -task :gen_deploy do - [:integrate, :generate, :deploy].each { |t| Rake::Task[t].execute } +task :gen_deploy => [:integrate, :generate, :deploy] do end desc "copy dot files for deployment" -task :copydot do - exclusions = [".", "..", ".DS_Store"] - Dir["#{source_dir}/**/.*"].each do |file| - if !File.directory?(file) && !exclusions.include?(file) - cp(file, file.gsub(/#{source_dir}/, "#{public_dir}")); - end +task :copydot, :source, :dest do |t, args| + FileList["#{args.source}/**/.*"].exclude("**/.", "**/..", "**/.DS_Store", "**/._*").each do |file| + cp_r file, file.gsub(/#{args.source}/, "#{args.dest}") unless File.directory?(file) end end desc "Deploy website via rsync" task :rsync do + exclude = "" + if File.exists?('./rsync-exclude') + exclude = "--exclude-from '#{File.expand_path('./rsync-exclude')}'" + end puts "## Deploying website via Rsync" - ok_failed system("rsync -avz --delete #{public_dir}/ #{ssh_user}:#{document_root}") + ok_failed system("rsync -avze 'ssh -p #{ssh_port}' #{exclude} #{"--delete" unless rsync_delete == false} #{public_dir}/ #{ssh_user}:#{document_root}") end desc "deploy public directory to github pages" multitask :push do puts "## Deploying branch to Github Pages " (Dir["#{deploy_dir}/*"]).each { |f| rm_rf(f) } - system "cp -R #{public_dir}/* #{deploy_dir}" + Rake::Task[:copydot].invoke(public_dir, deploy_dir) puts "\n## copying #{public_dir} to #{deploy_dir}" + cp_r "#{public_dir}/.", deploy_dir cd "#{deploy_dir}" do system "git add ." system "git add -u" puts "\n## Commiting: Site updated at #{Time.now.utc}" message = "Site updated at #{Time.now.utc}" - system "git commit -m '#{message}'" + system "git commit -m \"#{message}\"" puts "\n## Pushing generated #{deploy_dir} website" - system "git push origin #{deploy_branch}" + system "git push origin #{deploy_branch} --force" puts "\n## Github Pages deploy complete" end end @@ -274,25 +294,58 @@ task :set_root_dir, :dir do |t, args| end end -desc "Setup _deploy folder and deploy branch" -task :config_deploy, :branch do |t, args| - puts "!! Please provide a deploy branch, eg. rake init_deploy[gh-pages] !!" unless args.branch - puts "## Creating a clean #{args.branch} branch in ./#{deploy_dir} for Github pages deployment" +desc "Set up _deploy folder and deploy branch for Github Pages deployment" +task :setup_github_pages, :repo do |t, args| + if args.repo + repo_url = args.repo + else + repo_url = get_stdin("Enter the read/write url for your repository: ") + end + user = repo_url.match(/:([^\/]+)/)[1] + branch = (repo_url.match(/\/[\w-]+.github.com/).nil?) ? 'gh-pages' : 'master' + project = (branch == 'gh-pages') ? repo_url.match(/\/([^\.]+)/)[1] : '' + unless `git remote -v`.match(/origin.+?octopress.git/).nil? + # If octopress is still the origin remote (from cloning) rename it to octopress + system "git remote rename origin octopress" + if branch == 'master' + # If this is a user/organization pages repository, add the correct origin remote + # and checkout the source branch for committing changes to the blog source. + system "git remote add origin #{repo_url}" + puts "Added remote #{repo_url} as origin" + system "git config branch.master.remote origin" + puts "Set origin as default remote" + system "git branch -m master source" + puts "Master branch renamed to 'source' for committing your blog source files" + else + unless !public_dir.match("#{project}").nil? + system "rake set_root_dir[#{project}]" + end + end + end + url = "http://#{user}.github.com" + url += "/#{project}" unless project == '' + jekyll_config = IO.read('_config.yml') + jekyll_config.sub!(/^url:.*$/, "url: #{url}") + File.open('_config.yml', 'w') do |f| + f.write jekyll_config + end + rm_rf deploy_dir + mkdir deploy_dir cd "#{deploy_dir}" do - system "git symbolic-ref HEAD refs/heads/#{args.branch}" - system "rm .git/index" - system "git clean -fdx" + system "git init" system "echo 'My Octopress Page is coming soon …' > index.html" system "git add ." - system "git commit -m 'Octopress init'" + system "git commit -m \"Octopress init\"" + system "git branch -m gh-pages" unless branch == 'master' + system "git remote add origin #{repo_url}" rakefile = IO.read(__FILE__) - rakefile.sub!(/deploy_branch(\s*)=(\s*)(["'])[\w-]*["']/, "deploy_branch\\1=\\2\\3#{args.branch}\\3") + rakefile.sub!(/deploy_branch(\s*)=(\s*)(["'])[\w-]*["']/, "deploy_branch\\1=\\2\\3#{branch}\\3") rakefile.sub!(/deploy_default(\s*)=(\s*)(["'])[\w-]*["']/, "deploy_default\\1=\\2\\3push\\3") File.open(__FILE__, 'w') do |f| f.write rakefile end end - puts "## Deployment configured. Now you can deploy to the #{args.branch} branch with `rake deploy` ##" + puts "\n---\n## Now you can deploy to #{url} with `rake deploy` ##" end def ok_failed(condition) diff --git a/_config.yml b/_config.yml index 6d472bf6..fb296841 100644 --- a/_config.yml +++ b/_config.yml @@ -7,6 +7,13 @@ title: My Octopress Blog subtitle: A blogging framework for hackers. author: Your Name simple_search: http://google.com/search +description: + +# Default date format is "ordinal" (resulting in "July 22nd 2007") +# You can customize the format as defined in +# http://www.ruby-doc.org/core-1.9.2/Time.html#method-i-strftime +# Additionally, %o will give you the ordinal representation of the day +date_format: "ordinal" # RSS / Email (optional) subscription links (change if using something like Feedburner) subscribe_rss: /atom.xml @@ -34,9 +41,11 @@ pagination_dir: blog # Directory base for pagination URLs eg. /blog/page/2/ recent_posts: 5 # Posts in the sidebar Recent Posts section excerpt_link: "Read on →" # "Continue reading" link text at the bottom of excerpted articles +titlecase: true # Converts page and post titles to titlecase + # list each of the sidebar modules you want to include, in the order you want them to appear. # To add custom asides, create files in /source/_includes/custom/asides/ and add them to the list like 'custom/asides/custom_aside_name.html' -default_asides: [asides/recent_posts.html, asides/github.html, asides/twitter.html, asides/delicious.html, asides/pinboard.html] +default_asides: [asides/recent_posts.html, asides/github.html, asides/twitter.html, asides/delicious.html, asides/pinboard.html, asides/googleplus.html] # Each layout uses the default asides, but they can have their own asides instead. Simply uncomment the lines below # and add an array with the asides you want to use. @@ -62,10 +71,15 @@ twitter_follow_button: true twitter_show_follower_count: false twitter_tweet_button: true -# Google Plus -google_plus_one: true +# Google +1 +google_plus_one: false google_plus_one_size: medium +# Google Plus Profile +# Hidden: No visible button, just add author information to search results +googleplus_user: +googleplus_hidden: false + # Pinboard pinboard_user: pinboard_count: 3 @@ -76,6 +90,10 @@ delicious_count: 3 # Disqus Comments disqus_short_name: +disqus_show_comment_count: false # Google Analytics google_analytics_tracking_id: + +# Facebook Like +facebook_like: false diff --git a/plugins/backtick_code_block.rb b/plugins/backtick_code_block.rb index 7f5076df..40e7900b 100644 --- a/plugins/backtick_code_block.rb +++ b/plugins/backtick_code_block.rb @@ -10,7 +10,7 @@ module BacktickCodeBlock @lang = nil @url = nil @title = nil - input.gsub /^`{3} *([^\n]+)?\n(.+?)\n`{3}/m do + input.gsub(/^`{3} *([^\n]+)?\n(.+?)\n`{3}/m) do @options = $1 || '' str = $2 @@ -22,12 +22,12 @@ module BacktickCodeBlock @caption = "<figcaption><span>#{$2}</span></figcaption>" end - if str.match(/\A {4}/) - str = str.gsub /^ {4}/, '' + if str.match(/\A( {4}|\t)/) + str = str.gsub(/^( {4}|\t)/, '') end if @lang.nil? || @lang == 'plain' code = tableize_code(str.gsub('<','<').gsub('>','>')) - "<figure role=code>#{@caption}#{code}</figure>" + "<figure class='code'>#{@caption}#{code}</figure>" else if @lang.include? "-raw" raw = "``` #{@options.sub('-raw', '')}\n" @@ -35,7 +35,7 @@ module BacktickCodeBlock raw += "\n```\n" else code = highlight(str, @lang) - "<figure role=code>#{@caption}#{code}</figure>" + "<figure class='code'>#{@caption}#{code}</figure>" end end end diff --git a/plugins/blockquote.rb b/plugins/blockquote.rb index a0bf12cc..62e7d143 100644 --- a/plugins/blockquote.rb +++ b/plugins/blockquote.rb @@ -46,7 +46,7 @@ module Jekyll end def render(context) - quote = paragraphize(super.map(&:strip).join) + quote = paragraphize(super) author = "<strong>#{@by.strip}</strong>" if @by if @source url = @source.match(/https?:\/\/(.+)/)[1].split('/') @@ -60,9 +60,9 @@ module Jekyll source << '/…' unless source == @source end if !@source.nil? - cite = "<cite><a href='#{@source}'>#{(@title || source)}</a></cite>" + cite = " <cite><a href='#{@source}'>#{(@title || source)}</a></cite>" elsif !@title.nil? - cite = "<cite>#{@title}</cite>" + cite = " <cite>#{@title}</cite>" end blockquote = if @by.nil? quote @@ -75,7 +75,7 @@ module Jekyll end def paragraphize(input) - "<p>#{input.gsub(/\n\n/, '</p><p>').gsub(/\n/, '<br/>')}</p>" + "<p>#{input.lstrip.rstrip.gsub(/\n\n/, '</p><p>').gsub(/\n/, '<br/>')}</p>" end end end diff --git a/plugins/category_generator.rb b/plugins/category_generator.rb index d9357bc8..bb5fd329 100644 --- a/plugins/category_generator.rb +++ b/plugins/category_generator.rb @@ -48,6 +48,35 @@ module Jekyll end + # The CategoryFeed class creates an Atom feed for the specified category. + class CategoryFeed < Page + + # Initializes a new CategoryFeed. + # + # +base+ is the String path to the <source>. + # +category_dir+ is the String path between <source> and the category folder. + # +category+ is the category currently being processed. + def initialize(site, base, category_dir, category) + @site = site + @base = base + @dir = category_dir + @name = 'atom.xml' + self.process(@name) + # Read the YAML data from the layout page. + self.read_yaml(File.join(base, '_includes/custom'), 'category_feed.xml') + self.data['category'] = category + # Set the title for this page. + title_prefix = site.config['category_title_prefix'] || 'Category: ' + self.data['title'] = "#{title_prefix}#{category}" + # Set the meta-description for this page. + meta_description_prefix = site.config['category_meta_description_prefix'] || 'Category: ' + self.data['description'] = "#{meta_description_prefix}#{category}" + + # Set the correct feed URL. + self.data['feed_url'] = "#{category_dir}/#{name}" + end + + end # The Site class is a built-in Jekyll class with access to global site config information. class Site @@ -63,6 +92,13 @@ module Jekyll index.write(self.dest) # Record the fact that this page has been added, otherwise Site::cleanup will remove it. self.pages << index + + # Create an Atom-feed for each index. + feed = CategoryFeed.new(self, self.source, category_dir, category) + feed.render(self.layouts, site_payload) + feed.write(self.dest) + # Record the fact that this page has been added, otherwise Site::cleanup will remove it. + self.pages << feed end # Loops through the list of category pages and processes each one. diff --git a/plugins/code_block.rb b/plugins/code_block.rb index 00b0b438..44e34945 100644 --- a/plugins/code_block.rb +++ b/plugins/code_block.rb @@ -24,7 +24,7 @@ # # Output: # -# <figure role=code> +# <figure class='code'> # <figcaption><span>Got pain? painrelief.sh</span> <a href="http://site.com/painrelief.sh">Download it!</a> # <div class="highlight"><pre><code class="sh"> # -- nicely escaped highlighted code -- @@ -37,7 +37,7 @@ # <sarcasm>Ooooh, sarcasm... How original!</sarcasm> # {% endcodeblock %} # -# <figure role=code> +# <figure class='code'> # <pre><code><sarcasm> Ooooh, sarcasm... How original!</sarcasm></code></pre> # </figure> # @@ -79,8 +79,8 @@ module Jekyll def render(context) output = super - code = super.join - source = "<figure role=code>" + code = super + source = "<figure class='code'>" source += @caption if @caption if @filetype source += " #{highlight(code, @filetype)}</figure>" @@ -90,6 +90,7 @@ module Jekyll source = safe_wrap(source) source = context['pygments_prefix'] + source if context['pygments_prefix'] source = source + context['pygments_suffix'] if context['pygments_suffix'] + source end end end diff --git a/plugins/compass_compiler.rb b/plugins/compass_compiler.rb deleted file mode 100644 index dcec746a..00000000 --- a/plugins/compass_compiler.rb +++ /dev/null @@ -1 +0,0 @@ -system "compass compile --css-dir source/stylesheets" diff --git a/plugins/date.rb b/plugins/date.rb new file mode 100644 index 00000000..b864f3e9 --- /dev/null +++ b/plugins/date.rb @@ -0,0 +1,98 @@ +module Octopress + module Date + + # Returns a datetime if the input is a string + def datetime(date) + if date.class == String + date = Time.parse(date) + end + date + end + + # Returns an ordidinal date eg July 22 2007 -> July 22nd 2007 + def ordinalize(date) + date = datetime(date) + "#{date.strftime('%b')} #{ordinal(date.strftime('%e').to_i)}, #{date.strftime('%Y')}" + end + + # Returns an ordinal number. 13 -> 13th, 21 -> 21st etc. + def ordinal(number) + if (11..13).include?(number.to_i % 100) + "#{number}<span>th</span>" + else + case number.to_i % 10 + when 1; "#{number}<span>st</span>" + when 2; "#{number}<span>nd</span>" + when 3; "#{number}<span>rd</span>" + else "#{number}<span>th</span>" + end + end + end + + # Formats date either as ordinal or by given date format + # Adds %o as ordinal representation of the day + def format_date(date, format) + date = datetime(date) + if format.nil? || format.empty? || format == "ordinal" + date_formatted = ordinalize(date) + else + date_formatted = date.strftime(format) + date_formatted.gsub!(/%o/, ordinal(date.strftime('%e').to_i)) + end + date_formatted + end + + end +end + + +module Jekyll + + class Post + include Octopress::Date + + # Convert this post into a Hash for use in Liquid templates. + # + # Returns <Hash> + def to_liquid + date_format = self.site.config['date_format'] + self.data.deep_merge({ + "title" => self.data['title'] || self.slug.split('-').select {|w| w.capitalize! || w }.join(' '), + "url" => self.url, + "date" => self.date, + # Monkey patch + "date_formatted" => format_date(self.date, date_format), + "updated_formatted" => self.data.has_key?('updated') ? format_date(self.data['updated'], date_format) : nil, + "id" => self.id, + "categories" => self.categories, + "next" => self.next, + "previous" => self.previous, + "tags" => self.tags, + "content" => self.content }) + end + end + + class Page + include Octopress::Date + + # Initialize a new Page. + # + # site - The Site object. + # base - The String path to the source. + # dir - The String path between the source and the file. + # name - The String filename of the file. + def initialize(site, base, dir, name) + @site = site + @base = base + @dir = dir + @name = name + + self.process(name) + self.read_yaml(File.join(base, dir), name) + # Monkey patch + date_format = self.site.config['date_format'] + self.data['date_formatted'] = format_date(self.data['date'], date_format) if self.data.has_key?('date') + self.data['updated_formatted'] = format_date(self.data['updated'], date_format) if self.data.has_key?('updated') + end + end +end
\ No newline at end of file diff --git a/plugins/gist_tag.rb b/plugins/gist_tag.rb index 946ea23f..74dd3b37 100644 --- a/plugins/gist_tag.rb +++ b/plugins/gist_tag.rb @@ -16,7 +16,7 @@ module Jekyll super @text = text @cache_disabled = false - @cache_folder = File.expand_path "../_gist_cache", File.dirname(__FILE__) + @cache_folder = File.expand_path "../.gist-cache", File.dirname(__FILE__) FileUtils.mkdir_p @cache_folder end @@ -71,7 +71,13 @@ module Jekyll def get_gist_from_web(gist, file) gist_url = get_gist_url_for gist, file raw_uri = URI.parse gist_url - https = Net::HTTP.new raw_uri.host, raw_uri.port + proxy = ENV['http_proxy'] + if proxy + proxy_uri = URI.parse(proxy) + https = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port).new raw_uri.host, raw_uri.port + else + https = Net::HTTP.new raw_uri.host, raw_uri.port + end https.use_ssl = true https.verify_mode = OpenSSL::SSL::VERIFY_NONE request = Net::HTTP::Get.new raw_uri.request_uri diff --git a/plugins/image_tag.rb b/plugins/image_tag.rb index 25a38df5..45670007 100644 --- a/plugins/image_tag.rb +++ b/plugins/image_tag.rb @@ -1,46 +1,47 @@ # Title: Simple Image tag for Jekyll -# Author: Brandon Mathis http://brandonmathis.com -# Description: Easily output images with optional class names and title/alt attributes +# Authors: Brandon Mathis http://brandonmathis.com +# Felix Schäfer, Frederic Hemberger +# Description: Easily output images with optional class names, width, height, title and alt attributes # -# Syntax {% image [class name(s)] url [title text] %} +# Syntax {% img [class name(s)] [http[s]:/]/path/to/image [width [height]] [title text | "title text" ["alt text"]] %} # -# Example: -# {% ima left half http://site.com/images/ninja.png Ninja Attack! %} +# Examples: +# {% img /images/ninja.png Ninja Attack! %} +# {% img left half http://site.com/images/ninja.png Ninja Attack! %} +# {% img left half http://site.com/images/ninja.png 150 150 "Ninja Attack!" "Ninja in attack posture" %} # # Output: -# <image class='left' src="http://site.com/images/ninja.png" title="Ninja Attack!" alt="Ninja Attack!"> +# <img src="/images/ninja.png"> +# <img class="left half" src="http://site.com/images/ninja.png" title="Ninja Attack!" alt="Ninja Attack!"> +# <img class="left half" src="http://site.com/images/ninja.png" width="150" height="150" title="Ninja Attack!" alt="Ninja in attack posture"> # module Jekyll class ImageTag < Liquid::Tag @img = nil - @title = nil - @class = '' - @width = '' - @height = '' def initialize(tag_name, markup, tokens) - if markup =~ /(\S.*\s+)?(https?:\/\/|\/)(\S+)(\s+\d+\s+\d+)?(\s+.+)?/i - @class = $1 || '' - @img = $2 + $3 - if $5 - @title = $5.strip - end - if $4 =~ /\s*(\d+)\s+(\d+)/ - @width = $1 - @height = $2 + attributes = ['class', 'src', 'width', 'height', 'title'] + + if markup =~ /(?<class>\S.*\s+)?(?<src>(?:https?:\/\/|\/|\S+\/)\S+)(?:\s+(?<width>\d+))?(?:\s+(?<height>\d+))?(?<title>\s+.+)?/i + @img = attributes.reduce({}) { |img, attr| img[attr] = $~[attr].strip if $~[attr]; img } + if /(?:"|')(?<title>[^"']+)?(?:"|')\s+(?:"|')(?<alt>[^"']+)?(?:"|')/ =~ @img['title'] + @img['title'] = title + @img['alt'] = alt + else + @img['alt'] = @img['title'].gsub!(/"/, '"') if @img['title'] end + @img['class'].gsub!(/"/, '') if @img['class'] end super end def render(context) - output = super if @img - "<img class='#{@class}' src='#{@img}' width='#{@width}' height='#{@height}' alt='#{@title}' title='#{@title}'>" + "<img #{@img.collect {|k,v| "#{k}=\"#{v}\"" if v}.join(" ")}>" else - "Error processing input, expected syntax: {% img [class name(s)] /url/to/image [width height] [title text] %}" + "Error processing input, expected syntax: {% img [class name(s)] [http[s]:/]/path/to/image [width [height]] [title text | \"title text\" [\"alt text\"]] %}" end end end diff --git a/plugins/include_code.rb b/plugins/include_code.rb index 80951cb5..fc6daa36 100644 --- a/plugins/include_code.rb +++ b/plugins/include_code.rb @@ -61,7 +61,7 @@ module Jekyll @filetype = file.extname.sub('.','') if @filetype.nil? title = @title ? "#{@title} (#{file.basename})" : file.basename url = "/#{code_dir}/#{@file}" - source = "<figure role=code><figcaption><span>#{title}</span> <a href='#{url}'>download</a></figcaption>\n" + source = "<figure class='code'><figcaption><span>#{title}</span> <a href='#{url}'>download</a></figcaption>\n" source += " #{highlight(code, @filetype)}</figure>" safe_wrap(source) end diff --git a/plugins/jsfiddle.rb b/plugins/jsfiddle.rb new file mode 100644 index 00000000..3ae173eb --- /dev/null +++ b/plugins/jsfiddle.rb @@ -0,0 +1,40 @@ +# Title: jsFiddle tag for Jekyll +# Author: Brian Arnold (@brianarn) +# Description: +# Given a jsFiddle shortcode, outputs the jsFiddle iframe code. +# Using 'default' will preserve defaults as specified by jsFiddle. +# +# Syntax: {% jsfiddle shorttag [tabs] [skin] [height] [width] %} +# +# Examples: +# +# Input: {% jsfiddle ccWP7 %} +# Output: <iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/ccWP7/embedded/js,resources,html,css,result/light/"></iframe> +# +# Input: {% jsfiddle ccWP7 js,html,result %} +# Output: <iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/ccWP7/embedded/js,html,result/light/"></iframe> +# + +module Jekyll + class JsFiddle < Liquid::Tag + def initialize(tag_name, markup, tokens) + if /(?<fiddle>\w+)(?:\s+(?<sequence>[\w,]+))?(?:\s+(?<skin>\w+))?(?:\s+(?<height>\w+))?(?:\s+(?<width>\w+))?/ =~ markup + @fiddle = fiddle + @sequence = (sequence unless sequence == 'default') || 'js,resources,html,css,result' + @skin = (skin unless skin == 'default') || 'light' + @width = width || '100%' + @height = height || '300px' + end + end + + def render(context) + if @fiddle + "<iframe style=\"width: #{@width}; height: #{@height}\" src=\"http://jsfiddle.net/#{@fiddle}/embedded/#{@sequence}/#{@skin}/\"></iframe>" + else + "Error processing input, expected syntax: {% jsfiddle shorttag [tabs] [skin] [height] [width] %}" + end + end + end +end + +Liquid::Template.register_tag('jsfiddle', Jekyll::JsFiddle)
\ No newline at end of file diff --git a/plugins/octopress_filters.rb b/plugins/octopress_filters.rb index 1a959892..2ba93e9e 100644 --- a/plugins/octopress_filters.rb +++ b/plugins/octopress_filters.rb @@ -2,6 +2,7 @@ require './plugins/backtick_code_block' require './plugins/post_filters' require './plugins/raw' +require './plugins/date' require 'rubypants' module OctopressFilters @@ -23,16 +24,22 @@ module Jekyll class ContentFilters < PostFilter include OctopressFilters def pre_render(post) - post.content = pre_filter(post.content) + if post.ext.match('html|textile|markdown|haml|slim|xml') + post.content = pre_filter(post.content) + end end def post_render(post) - post.content = post_filter(post.content) + if post.ext.match('html|textile|markdown|haml|slim|xml') + post.content = post_filter(post.content) + end end end end module OctopressLiquidFilters + include Octopress::Date + # Used on the blog index to split posts on the <!--more--> marker def excerpt(input) if input.index(/<!--\s*more\s*-->/i) @@ -56,6 +63,18 @@ module OctopressLiquidFilters end end + # Extracts raw content DIV from template, used for page description as {{ content }} + # contains complete sub-template code on main page level + def raw_content(input) + /<div class="entry-content">(?<content>[\s\S]*?)<\/div>\s*<(footer|\/article)>/ =~ input + return (content.nil?) ? input : content + end + + # Escapes CDATA sections in post content + def cdata_escape(input) + input.gsub(/<!\[CDATA\[/, '<![CDATA[').gsub(/\]\]>/, ']]>') + end + # Replaces relative urls with full urls def expand_urls(input, url='') url ||= '/' @@ -64,6 +83,33 @@ module OctopressLiquidFilters end end + # Improved version of Liquid's truncate: + # - Doesn't cut in the middle of a word. + # - Uses typographically correct ellipsis (…) insted of '...' + def truncate(input, length) + if input.length > length && input[0..(length-1)] =~ /(.+)\b.+$/im + $1.strip + ' …' + else + input + end + end + + # Improved version of Liquid's truncatewords: + # - Uses typographically correct ellipsis (…) insted of '...' + def truncatewords(input, length) + truncate = input.split(' ') + if truncate.length > length + truncate[0..length-1].join(' ').strip + ' …' + else + input + end + end + + # Condenses multiple spaces and tabs into a single space + def condense_spaces(input) + input.gsub(/\s{2,}/, ' ') + end + # Removes trailing forward slash from a string for easily appending url segments def strip_slash(input) if input =~ /(.+)\/$|^\/$/ @@ -84,33 +130,6 @@ module OctopressLiquidFilters input.titlecase end - # Returns a datetime if the input is a string - def datetime(date) - if date.class == String - date = Time.parse(date) - end - date - end - - # Returns an ordidinal date eg July 22 2007 -> July 22nd 2007 - def ordinalize(date) - date = datetime(date) - "#{date.strftime('%b')} #{ordinal(date.strftime('%e').to_i)}, #{date.strftime('%Y')}" - end - - # Returns an ordinal number. 13 -> 13th, 21 -> 21st etc. - def ordinal(number) - if (11..13).include?(number.to_i % 100) - "#{number}<span>th</span>" - else - case number.to_i % 10 - when 1; "#{number}<span>st</span>" - when 2; "#{number}<span>nd</span>" - when 3; "#{number}<span>rd</span>" - else "#{number}<span>th</span>" - end - end - end end Liquid::Template.register_filter OctopressLiquidFilters diff --git a/plugins/preview_unpublished.rb b/plugins/preview_unpublished.rb new file mode 100644 index 00000000..321ffd6f --- /dev/null +++ b/plugins/preview_unpublished.rb @@ -0,0 +1,48 @@ +# Monkeypatch for Jekyll +# Introduce distinction between preview/productive site generation +# so posts with YAML attribute `published: false` can be previewed +# on localhost without being published to the productive environment. + +module Jekyll + + class Site + # Read all the files in <source>/<dir>/_posts and create a new Post + # object with each one. + # + # dir - The String relative path of the directory to read. + # + # Returns nothing. + def read_posts(dir) + base = File.join(self.source, dir, '_posts') + return unless File.exists?(base) + entries = Dir.chdir(base) { filter_entries(Dir['**/*']) } + + # first pass processes, but does not yet render post content + entries.each do |f| + if Post.valid?(f) + post = Post.new(self, self.source, dir, f) + + # Monkeypatch: + # On preview environment (localhost), publish all posts + if ENV.has_key?('OCTOPRESS_ENV') && ENV['OCTOPRESS_ENV'] == 'preview' && post.data.has_key?('published') && post.data['published'] == false + post.published = true + # Set preview mode flag (if necessary), `rake generate` will check for it + # to prevent pushing preview posts to productive environment + File.open(".preview-mode", "w") {} + end + + if post.published && (self.future || post.date <= self.time) + self.posts << post + post.categories.each { |c| self.categories[c] << post } + post.tags.each { |c| self.tags[c] << post } + end + end + end + + self.posts.sort! + + # limit the posts if :limit_posts option is set + self.posts = self.posts[-limit_posts, limit_posts] if limit_posts + end + end +end
\ No newline at end of file diff --git a/plugins/pullquote.rb b/plugins/pullquote.rb index 03e307a7..3c65e66e 100644 --- a/plugins/pullquote.rb +++ b/plugins/pullquote.rb @@ -1,6 +1,6 @@ # # Author: Brandon Mathis -# Based on the sematic pullquote technique by Maykel Loomans at http://miekd.com/articles/pull-quotes-with-html5-and-css/ +# Based on the semantic pullquote technique by Maykel Loomans at http://miekd.com/articles/pull-quotes-with-html5-and-css/ # # Outputs a span with a data-pullquote attribute set from the marked pullquote. Example: # @@ -13,23 +13,28 @@ # <p> # <span data-pullquote="pullquotes are merely visual in presentation and should not appear twice in the text."> # When writing longform posts, I find it helpful to include pullquotes, which help those scanning a post discern whether or not a post is helpful. -# It is important to note, pullquotes are merely visual in presentation and should not appear twice in the text. This is why a CSS only approach # for styling pullquotes is prefered. +# It is important to note, pullquotes are merely visual in presentation and should not appear twice in the text. This is why a CSS only approach +# for styling pullquotes is prefered. # </span> # </p> # +# {% pullquote left %} will create a left-aligned pullquote instead. +# +# Note: this plugin now creates pullquotes with the class of pullquote-right by default module Jekyll class PullquoteTag < Liquid::Block def initialize(tag_name, markup, tokens) + @align = (markup =~ /left/i) ? "left" : "right" super end def render(context) output = super - if output.join =~ /\{"\s*(.+)\s*"\}/ - @quote = $1 - "<span class='has-pullquote' data-pullquote='#{@quote}'>#{output.join.gsub(/\{"\s*|\s*"\}/, '')}</span>" + if output =~ /\{"\s*(.+?)\s*"\}/m + @quote = RubyPants.new($1).to_html + "<span class='pullquote-#{@align}' data-pullquote='#{@quote}'>#{output.gsub(/\{"\s*|\s*"\}/, '')}</span>" else return "Surround your pullquote like this {\" text to be quoted \"}" end diff --git a/plugins/pygments_code.rb b/plugins/pygments_code.rb index 67ce8c34..1676a3e0 100644 --- a/plugins/pygments_code.rb +++ b/plugins/pygments_code.rb @@ -2,7 +2,7 @@ require 'pygments' require 'fileutils' require 'digest/md5' -PYGMENTS_CACHE_DIR = File.expand_path('../../_code_cache', __FILE__) +PYGMENTS_CACHE_DIR = File.expand_path('../../.pygments-cache', __FILE__) FileUtils.mkdir_p(PYGMENTS_CACHE_DIR) module HighlightCode @@ -21,21 +21,21 @@ module HighlightCode if File.exist?(path) highlighted_code = File.read(path) else - highlighted_code = Pygments.highlight(code, :lexer => lang, :formatter => 'html') + highlighted_code = Pygments.highlight(code, :lexer => lang, :formatter => 'html', :options => {:encoding => 'utf-8'}) File.open(path, 'w') {|f| f.print(highlighted_code) } end else - highlighted_code = Pygments.highlight(code, :lexer => lang, :formatter => 'html') + highlighted_code = Pygments.highlight(code, :lexer => lang, :formatter => 'html', :options => {:encoding => 'utf-8'}) end highlighted_code end def tableize_code (str, lang = '') - table = '<div class="highlight"><table cellpadding="0" cellspacing="0"><tr><td class="gutter"><pre class="line-numbers">' + table = '<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers">' code = '' str.lines.each_with_index do |line,index| - table += "<span class='line'>#{index+1}</span>\n" - code += "<div class='line'>#{line}</div>" + table += "<span class='line-number'>#{index+1}</span>\n" + code += "<span class='line'>#{line}</span>" end - table += "</pre></td><td class='code' width='100%'><pre><code class='#{lang}'>#{code}</code></pre></td></tr></table></div>" + table += "</pre></td><td class='code'><pre><code class='#{lang}'>#{code}</code></pre></td></tr></table></div>" end end diff --git a/plugins/rubypants.rb b/plugins/rubypants.rb new file mode 100644 index 00000000..e4f4502f --- /dev/null +++ b/plugins/rubypants.rb @@ -0,0 +1,489 @@ +# +# = RubyPants -- SmartyPants ported to Ruby +# +# Ported by Christian Neukirchen <mailto:chneukirchen@gmail.com> +# Copyright (C) 2004 Christian Neukirchen +# +# Incooporates ideas, comments and documentation by Chad Miller +# Copyright (C) 2004 Chad Miller +# +# Original SmartyPants by John Gruber +# Copyright (C) 2003 John Gruber +# + +# +# = RubyPants -- SmartyPants ported to Ruby +# +# == Synopsis +# +# RubyPants is a Ruby port of the smart-quotes library SmartyPants. +# +# The original "SmartyPants" is a free web publishing plug-in for +# Movable Type, Blosxom, and BBEdit that easily translates plain ASCII +# punctuation characters into "smart" typographic punctuation HTML +# entities. +# +# +# == Description +# +# RubyPants can perform the following transformations: +# +# * Straight quotes (<tt>"</tt> and <tt>'</tt>) into "curly" quote +# HTML entities +# * Backticks-style quotes (<tt>``like this''</tt>) into "curly" quote +# HTML entities +# * Dashes (<tt>--</tt> and <tt>---</tt>) into en- and em-dash +# entities +# * Three consecutive dots (<tt>...</tt> or <tt>. . .</tt>) into an +# ellipsis entity +# +# This means you can write, edit, and save your posts using plain old +# ASCII straight quotes, plain dashes, and plain dots, but your +# published posts (and final HTML output) will appear with smart +# quotes, em-dashes, and proper ellipses. +# +# RubyPants does not modify characters within <tt><pre></tt>, +# <tt><code></tt>, <tt><kbd></tt>, <tt><math></tt> or +# <tt><script></tt> tag blocks. Typically, these tags are used to +# display text where smart quotes and other "smart punctuation" would +# not be appropriate, such as source code or example markup. +# +# +# == Backslash Escapes +# +# If you need to use literal straight quotes (or plain hyphens and +# periods), RubyPants accepts the following backslash escape sequences +# to force non-smart punctuation. It does so by transforming the +# escape sequence into a decimal-encoded HTML entity: +# +# \\ \" \' \. \- \` +# +# This is useful, for example, when you want to use straight quotes as +# foot and inch marks: 6'2" tall; a 17" iMac. (Use <tt>6\'2\"</tt> +# resp. <tt>17\"</tt>.) +# +# +# == Algorithmic Shortcomings +# +# One situation in which quotes will get curled the wrong way is when +# apostrophes are used at the start of leading contractions. For +# example: +# +# 'Twas the night before Christmas. +# +# In the case above, RubyPants will turn the apostrophe into an +# opening single-quote, when in fact it should be a closing one. I +# don't think this problem can be solved in the general case--every +# word processor I've tried gets this wrong as well. In such cases, +# it's best to use the proper HTML entity for closing single-quotes +# ("<tt>’</tt>") by hand. +# +# +# == Bugs +# +# To file bug reports or feature requests (except see above) please +# send email to: mailto:chneukirchen@gmail.com +# +# If the bug involves quotes being curled the wrong way, please send +# example text to illustrate. +# +# +# == Authors +# +# John Gruber did all of the hard work of writing this software in +# Perl for Movable Type and almost all of this useful documentation. +# Chad Miller ported it to Python to use with Pyblosxom. +# +# Christian Neukirchen provided the Ruby port, as a general-purpose +# library that follows the *Cloth API. +# +# +# == Copyright and License +# +# === SmartyPants license: +# +# Copyright (c) 2003 John Gruber +# (http://daringfireball.net) +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name "SmartyPants" nor the names of its contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# This software is provided by the copyright holders and contributors +# "as is" and any express or implied warranties, including, but not +# limited to, the implied warranties of merchantability and fitness +# for a particular purpose are disclaimed. In no event shall the +# copyright owner or contributors be liable for any direct, indirect, +# incidental, special, exemplary, or consequential damages (including, +# but not limited to, procurement of substitute goods or services; +# loss of use, data, or profits; or business interruption) however +# caused and on any theory of liability, whether in contract, strict +# liability, or tort (including negligence or otherwise) arising in +# any way out of the use of this software, even if advised of the +# possibility of such damage. +# +# === RubyPants license +# +# RubyPants is a derivative work of SmartyPants and smartypants.py. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# This software is provided by the copyright holders and contributors +# "as is" and any express or implied warranties, including, but not +# limited to, the implied warranties of merchantability and fitness +# for a particular purpose are disclaimed. In no event shall the +# copyright owner or contributors be liable for any direct, indirect, +# incidental, special, exemplary, or consequential damages (including, +# but not limited to, procurement of substitute goods or services; +# loss of use, data, or profits; or business interruption) however +# caused and on any theory of liability, whether in contract, strict +# liability, or tort (including negligence or otherwise) arising in +# any way out of the use of this software, even if advised of the +# possibility of such damage. +# +# +# == Links +# +# John Gruber:: http://daringfireball.net +# SmartyPants:: http://daringfireball.net/projects/smartypants +# +# Chad Miller:: http://web.chad.org +# +# Christian Neukirchen:: http://kronavita.de/chris +# + + +class RubyPants < String + + # Create a new RubyPants instance with the text in +string+. + # + # Allowed elements in the options array: + # + # 0 :: do nothing + # 1 :: enable all, using only em-dash shortcuts + # 2 :: enable all, using old school en- and em-dash shortcuts (*default*) + # 3 :: enable all, using inverted old school en and em-dash shortcuts + # -1 :: stupefy (translate HTML entities to their ASCII-counterparts) + # + # If you don't like any of these defaults, you can pass symbols to change + # RubyPants' behavior: + # + # <tt>:quotes</tt> :: quotes + # <tt>:backticks</tt> :: backtick quotes (``double'' only) + # <tt>:allbackticks</tt> :: backtick quotes (``double'' and `single') + # <tt>:dashes</tt> :: dashes + # <tt>:oldschool</tt> :: old school dashes + # <tt>:inverted</tt> :: inverted old school dashes + # <tt>:ellipses</tt> :: ellipses + # <tt>:convertquotes</tt> :: convert <tt>"</tt> entities to + # <tt>"</tt> for Dreamweaver users + # <tt>:stupefy</tt> :: translate RubyPants HTML entities + # to their ASCII counterparts. + # + def initialize(string, options=[2]) + super string + @options = [*options] + end + + # Apply SmartyPants transformations. + def to_html + do_quotes = do_backticks = do_dashes = do_ellipses = do_stupify = nil + convert_quotes = false + + if @options.include? 0 + # Do nothing. + return self + elsif @options.include? 1 + # Do everything, turn all options on. + do_quotes = do_backticks = do_ellipses = true + do_dashes = :normal + elsif @options.include? 2 + # Do everything, turn all options on, use old school dash shorthand. + do_quotes = do_backticks = do_ellipses = true + do_dashes = :oldschool + elsif @options.include? 3 + # Do everything, turn all options on, use inverted old school + # dash shorthand. + do_quotes = do_backticks = do_ellipses = true + do_dashes = :inverted + elsif @options.include?(-1) + do_stupefy = true + else + do_quotes = @options.include? :quotes + do_backticks = @options.include? :backticks + do_backticks = :both if @options.include? :allbackticks + do_dashes = :normal if @options.include? :dashes + do_dashes = :oldschool if @options.include? :oldschool + do_dashes = :inverted if @options.include? :inverted + do_ellipses = @options.include? :ellipses + convert_quotes = @options.include? :convertquotes + do_stupefy = @options.include? :stupefy + end + + # Parse the HTML + tokens = tokenize + + # Keep track of when we're inside <pre> or <code> tags. + in_pre = false + + # Here is the result stored in. + result = "" + + # This is a cheat, used to get some context for one-character + # tokens that consist of just a quote char. What we do is remember + # the last character of the previous text token, to use as context + # to curl single- character quote tokens correctly. + prev_token_last_char = nil + + tokens.each { |token| + if token.first == :tag + result << token[1] + if token[1] =~ %r!<(/?)(?:pre|code|kbd|script|math)[\s>]! + in_pre = ($1 != "/") # Opening or closing tag? + end + else + t = token[1] + + # Remember last char of this token before processing. + last_char = t[-1].chr + + unless in_pre + t = process_escapes t + + t.gsub!(/"/, '"') if convert_quotes + + if do_dashes + t = educate_dashes t if do_dashes == :normal + t = educate_dashes_oldschool t if do_dashes == :oldschool + t = educate_dashes_inverted t if do_dashes == :inverted + end + + t = educate_ellipses t if do_ellipses + + # Note: backticks need to be processed before quotes. + if do_backticks + t = educate_backticks t + t = educate_single_backticks t if do_backticks == :both + end + + if do_quotes + if t == "'" + # Special case: single-character ' token + if prev_token_last_char =~ /\S/ + t = "’" + else + t = "‘" + end + elsif t == '"' + # Special case: single-character " token + if prev_token_last_char =~ /\S/ + t = "”" + else + t = "“" + end + else + # Normal case: + t = educate_quotes t + end + end + + t = stupefy_entities t if do_stupefy + end + + prev_token_last_char = last_char + result << t + end + } + + # Done + result + end + + protected + + # Return the string, with after processing the following backslash + # escape sequences. This is useful if you want to force a "dumb" quote + # or other character to appear. + # + # Escaped are: + # \\ \" \' \. \- \` + # + def process_escapes(str) + str.gsub('\\\\', '\'). + gsub('\"', '"'). + gsub("\\\'", '''). + gsub('\.', '.'). + gsub('\-', '-'). + gsub('\`', '`') + end + + # The string, with each instance of "<tt>--</tt>" translated to an + # em-dash HTML entity. + # + def educate_dashes(str) + str.gsub(/--/, '—') + end + + # The string, with each instance of "<tt>--</tt>" translated to an + # en-dash HTML entity, and each "<tt>---</tt>" translated to an + # em-dash HTML entity. + # + def educate_dashes_oldschool(str) + str.gsub(/---/, '—').gsub(/--/, '–') + end + + # Return the string, with each instance of "<tt>--</tt>" translated + # to an em-dash HTML entity, and each "<tt>---</tt>" translated to + # an en-dash HTML entity. Two reasons why: First, unlike the en- and + # em-dash syntax supported by +educate_dashes_oldschool+, it's + # compatible with existing entries written before SmartyPants 1.1, + # back when "<tt>--</tt>" was only used for em-dashes. Second, + # em-dashes are more common than en-dashes, and so it sort of makes + # sense that the shortcut should be shorter to type. (Thanks to + # Aaron Swartz for the idea.) + # + def educate_dashes_inverted(str) + str.gsub(/---/, '–').gsub(/--/, '—') + end + + # Return the string, with each instance of "<tt>...</tt>" translated + # to an ellipsis HTML entity. Also converts the case where there are + # spaces between the dots. + # + def educate_ellipses(str) + str.gsub('...', '…').gsub('. . .', '…') + end + + # Return the string, with "<tt>``backticks''</tt>"-style single quotes + # translated into HTML curly quote entities. + # + def educate_backticks(str) + str.gsub("``", '“').gsub("''", '”') + end + + # Return the string, with "<tt>`backticks'</tt>"-style single quotes + # translated into HTML curly quote entities. + # + def educate_single_backticks(str) + str.gsub("`", '‘').gsub("'", '’') + end + + # Return the string, with "educated" curly quote HTML entities. + # + def educate_quotes(str) + punct_class = '[!"#\$\%\'()*+,\-.\/:;<=>?\@\[\\\\\]\^_`{|}~]' + + str = str.dup + + # Special case if the very first character is a quote followed by + # punctuation at a non-word-break. Close the quotes by brute + # force: + str.gsub!(/^'(?=#{punct_class}\B)/, '’') + str.gsub!(/^"(?=#{punct_class}\B)/, '”') + + # Special case for double sets of quotes, e.g.: + # <p>He said, "'Quoted' words in a larger quote."</p> + str.gsub!(/"'(?=\w)/, '“‘') + str.gsub!(/'"(?=\w)/, '‘“') + + # Special case for decade abbreviations (the '80s): + str.gsub!(/'(?=\d\ds)/, '’') + + close_class = %![^\ \t\r\n\\[\{\(\-]! + dec_dashes = '–|—' + + # Get most opening single quotes: + str.gsub!(/(\s| |--|&[mn]dash;|#{dec_dashes}|ȁ[34];)'(?=\w)/, + '\1‘') + # Single closing quotes: + str.gsub!(/(#{close_class})'/, '\1’') + str.gsub!(/'(\s|s\b|$)/, '’\1') + # Any remaining single quotes should be opening ones: + str.gsub!(/'/, '‘') + + # Get most opening double quotes: + str.gsub!(/(\s| |--|&[mn]dash;|#{dec_dashes}|ȁ[34];)"(?=\w)/, + '\1“') + # Double closing quotes: + str.gsub!(/(#{close_class})"/, '\1”') + str.gsub!(/"(\s|s\b|$)/, '”\1') + # Any remaining quotes should be opening ones: + str.gsub!(/"/, '“') + + str + end + + # Return the string, with each RubyPants HTML entity translated to + # its ASCII counterpart. + # + # Note: This is not reversible (but exactly the same as in SmartyPants) + # + def stupefy_entities(str) + str. + gsub(/–/, '-'). # en-dash + gsub(/—/, '--'). # em-dash + + gsub(/‘/, "'"). # open single quote + gsub(/’/, "'"). # close single quote + + gsub(/“/, '"'). # open double quote + gsub(/”/, '"'). # close double quote + + gsub(/…/, '...') # ellipsis + end + + # Return an array of the tokens comprising the string. Each token is + # either a tag (possibly with nested, tags contained therein, such + # as <tt><a href="<MTFoo>"></tt>, or a run of text between + # tags. Each element of the array is a two-element array; the first + # is either :tag or :text; the second is the actual value. + # + # Based on the <tt>_tokenize()</tt> subroutine from Brad Choate's + # MTRegex plugin. <http://www.bradchoate.com/past/mtregex.php> + # + # This is actually the easier variant using tag_soup, as used by + # Chad Miller in the Python port of SmartyPants. + # + def tokenize + tag_soup = /([^<]*)(<[^>]*>)/ + + tokens = [] + + prev_end = 0 + scan(tag_soup) { + tokens << [:text, $1] if $1 != "" + tokens << [:tag, $2] + + prev_end = $~.end(0) + } + + if prev_end < size + tokens << [:text, self[prev_end..-1]] + end + + tokens + end +end diff --git a/plugins/titlecase.rb b/plugins/titlecase.rb index 103bf702..7648932c 100644 --- a/plugins/titlecase.rb +++ b/plugins/titlecase.rb @@ -11,8 +11,8 @@ class String # capitalize first and last words x.first.to_s.smart_capitalize! x.last.to_s.smart_capitalize! - # small words after colons are capitalized - x.join(" ").gsub(/:\s?(\W*#{small_words.join("|")}\W*)\s/) { ": #{$1.smart_capitalize} " } + # small words are capitalized after colon, period, exclamation mark, question mark + x.join(" ").gsub(/(:|\.|!|\?)\s?(\W*#{small_words.join("|")}\W*)\s/) { "#{$1} #{$2.smart_capitalize} " } end def titlecase! |