Easier Documentation, Simpler Websites & Faster Collaboration

Every minute an editor spends managing presentational tweaks is one they can’t spend on critical stories.


Jeff Eaton

Build your site

Automate!
A command typed in a terminal is a task automated.

Next
Install Awestruct

Check Your Ruby version

$ ruby --version
# ruby 1.9.3p848 (2013-11-22 revision 40747) [x86_64-linux]
You must use the 32-bit version of Ruby 1.9.3 on Windows.
Windows install steps:
  1. Download Ruby Installer from http://tiny.cc/ruby193win
  2. Run installer, select default location
  3. Check "Add Ruby executables to your PATH"
  4. Configure RubyGems:
    (echo install: --no-rdoc --no-ri) > C:\ProgramData\gemrc
    (echo update: --no-rdoc --no-ri) >> C:\ProgramData\gemrc

Install RVM

Linux and OSX
$ \curl -L https://get.rvm.io -o rvm-installer
$ bash rvm-installer --ruby=2.0.0
Windows

Use Ruby as normal. Skip any RVM steps.

The RVM equivalent for Windows is named pik.

Create and use a new Ruby gemset (RVM only)

$ rvm use 2.0.0@writeadapt --create
If you want to use Ruby 1.9.3, replace 2.0.0 with 1.9.3.

Install Awestruct

$ gem install tilt --version 1.4.1
$ gem install awestruct --version 0.5.4.rc3
$ gem install asciidoctor
Console output
Successfully installed tilt-1.4.1
1 gem installed

HEADS UP! Haml 4.0 has many improvements, but also has changes that may break
your application:

* Support for Ruby 1.8.6 dropped
* Support for Rails 2 dropped
* Sass filter now always outputs <style> tags
* Data attributes are now hyphenated, not underscored
* html2haml utility moved to the html2haml gem
* Textile and Maruku filters moved to the haml-contrib gem

For more info see:

http://rubydoc.info/github/haml/haml/file/CHANGELOG.md

Successfully installed haml-4.0.4
Building native extensions.  This could take a while...
Successfully installed nokogiri-1.5.10
Successfully installed rb-fsevent-0.9.3
Building native extensions.  This could take a while...
Successfully installed ffi-1.9.3
Successfully installed rb-inotify-0.9.2
Successfully installed rb-kqueue-0.2.0
Successfully installed listen-1.1.6
Successfully installed sass-3.3.0.rc.2
Successfully installed multi_json-1.8.2
Successfully installed compass-core-1.0.0.alpha.13
Successfully installed chunky_png-1.2.9
    Compass is charityware. If you love it, please donate on our behalf at http://umdf.org/compass Thanks!
Successfully installed compass-1.0.0.alpha.13
Successfully installed compass-960-plugin-0.10.4
Successfully installed bootstrap-sass-3.0.2.1
Successfully installed zurb-foundation-4.3.2
Successfully installed mime-types-1.25
Successfully installed rest-client-1.6.7
Successfully installed ruby-s3cmd-0.1.5
Successfully installed rack-1.5.2
Successfully installed awestruct-0.5.4.rc3
20 gems installed

Successfully installed asciidoctor-0.1.4
1 gem installed

Check version of Awestruct

$ awestruct --version
Console output
Awestruct: 0.5.4.rc3
http://awestruct.org/

Next
Setup a new Awestruct project

Create a project folder and switch to it

Make empty project directory
$ mkdir writeadapt
Switch to new directory
$ cd writeadapt
Don’t forget to switch to the new directory or else the website will be generated in the wrong location.

Generate website structure

$ awestruct -i -f foundation
Console output
Create directory: /home/dallen/tmp/awestruct/writeadapt/_config
Create directory: /home/dallen/tmp/awestruct/writeadapt/_layouts
Create directory: /home/dallen/tmp/awestruct/writeadapt/_ext
Create file: /home/dallen/tmp/awestruct/writeadapt/_ext/pipeline.rb
Create file: /home/dallen/tmp/awestruct/writeadapt/.awestruct_ignore
Create file: /home/dallen/tmp/awestruct/writeadapt/Rakefile
Create file: /home/dallen/tmp/awestruct/writeadapt/Gemfile
Create directory: /home/dallen/tmp/awestruct/writeadapt/stylesheets
directory _site/stylesheets/
directory javascripts/foundation/
directory javascripts/vendor/
   create stylesheets/_normalize.scss
   create stylesheets/_settings.scss
   create stylesheets/app.scss
   create humans.txt
   create robots.txt
   create MIT-LICENSE.txt
   create javascripts/foundation/foundation.orbit.js
   create javascripts/foundation/foundation.cookie.js
   create javascripts/foundation/foundation.clearing.js
   create javascripts/foundation/foundation.magellan.js
   create javascripts/foundation/foundation.section.js
   create javascripts/foundation/foundation.alerts.js
   create javascripts/foundation/foundation.topbar.js
   create javascripts/foundation/foundation.joyride.js
   create javascripts/foundation/foundation.interchange.js
   create javascripts/foundation/foundation.forms.js
   create javascripts/foundation/foundation.tooltips.js
   create javascripts/foundation/foundation.abide.js
   create javascripts/foundation/foundation.dropdown.js
   create javascripts/foundation/foundation.placeholder.js
   create javascripts/foundation/foundation.reveal.js
   create javascripts/vendor/custom.modernizr.js
   create javascripts/vendor/jquery.js
   create javascripts/vendor/zepto.js
   create javascripts/foundation/foundation.js
   create index.html
DEPRECATION WARNING on line 224 of /home/dallen/.rvm/gems/ruby-2.0.0-p353@writeadapt/gems/zurb-foundation-4.3.2/scss/foundation/components/_global.scss:
Assigning to global variable "$default-float" by default is deprecated.
In future versions of Sass, this will create a new local variable.
If you want to assign to the global variable, use "$default-float: left !global" instead.

DEPRECATION WARNING on line 225 of /home/dallen/.rvm/gems/ruby-2.0.0-p353@writeadapt/gems/zurb-foundation-4.3.2/scss/foundation/components/_global.scss:
Assigning to global variable "$opposite-direction" by default is deprecated.
In future versions of Sass, this will create a new local variable.
If you want to assign to the global variable, use "$opposite-direction: right !global" instead.

   create _site/stylesheets/app.css

Now you're awestruct!

To generate and run your site in development mode, execute:

  awestruct -d

or, simply:

  rake

then visit your site at: http://localhost:4242

Create file: /home/dallen/tmp/awestruct/writeadapt/_config/site.yml
Create file: /home/dallen/tmp/awestruct/writeadapt/_layouts/base.html.haml
Create file: /home/dallen/tmp/awestruct/writeadapt/index.html.haml

Setup Gemfile

$ cat > Gemfile << LINES
source 'https://rubygems.org'
gem 'awestruct', '0.5.4.rc3'
gem 'asciidoctor', '0.1.4'
gem 'tilt', '1.4.1'
gem 'rake', '>= 0.9.2'
gem 'git', '1.2.6'
LINES
On Windows, run notepad Gemfile, remove all text and paste the content between LINES from above.

Lock dependencies

$ gem install bundler
$ bundle install
Console output
Fetching: bundler-1.3.5.gem (100%)
Successfully installed bundler-1.3.5
1 gem installed

Fetching gem metadata from https://rubygems.org/...
Resolving dependencies...
Installing rake (10.1.0)
Using asciidoctor (0.1.4)
Installing sass (3.2.12)
Using bootstrap-sass (3.0.2.1)
Using chunky_png (1.2.9)
Installing fssm (0.2.10)
Installing compass (0.12.2)
Using compass-960-plugin (0.10.4)
Using tilt (1.4.1)
Using haml (4.0.4)
Using rb-fsevent (0.9.3)
Using ffi (1.9.3)
Using rb-inotify (0.9.2)
Using rb-kqueue (0.2.0)
Installing listen (1.3.1)
Using mime-types (1.25)
Using nokogiri (1.5.10)
Using rack (1.5.2)
Using rest-client (1.6.7)
Using ruby-s3cmd (0.1.5)
Using zurb-foundation (4.3.2)
Using awestruct (0.5.4.rc3)
Using bundler (1.3.5)
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.

Awestruct project file tree

 .awestruct/
 `-- debug.log
 .awestruct_ignore
 _config/
 `-- site.yml
 _ext/
 `-- pipeline.rb
 Gemfile
 humans.txt
 index.html.haml
 javascripts/
 |-- foundation/
 |   |-- foundation.alerts.js
 |   |-- ...
 |   |-- foundation.js
 |   |-- ...
 |   `-- foundation.topbar.js
 `-- vendor/
     |-- custom.modernizr.js
     |-- jquery.js
     `-- zepto.js
 _layouts/
 `-- base.html.haml
 Rakefile
 robots.txt
 _site/
 stylesheets/
 |-- app.scss
 |-- _normalize.scss
 `-- _settings.scss

Next
Preview Site

Generate and preview website

$ rake
The no-argument rake command is a alias for rake preview.
Console output
Running command: bundle exec awestruct -d
Using profile: development
Generating site: http://localhost:4242
***************************************************************************
Starting preview server at http://localhost:4242 (Press Ctrl-C to shutdown)
***************************************************************************
[Listen warning]:
The blocking parameter of Listen::Listener#start is deprecated.
Please use Listen::Adapter#start for a non-blocking listener and Listen::Listener#start! for a blocking one.
[2013-12-03 17:20:43] INFO  WEBrick 1.3.1
[2013-12-03 17:20:43] INFO  ruby 2.0.0 (2013-11-22) [x86_64-linux]
[2013-12-03 17:20:43] INFO  WEBrick::HTTPServer#start: pid=19591 port=4242
new awestruct foundation site desktop
Desktop view
new awestruct foundation site phone
Mobile view

Halt the preview server

Press key combo

Ctrl+C

Console output
...
[2013-01-01 00:00:00] INFO  going to shutdown ...
[2013-01-01 00:00:00] INFO  WEBrick::HTTPServer#start done.

Structure of generated site

_site/
|-- humans.txt
|-- index.html
|-- javascripts/
|   |-- foundation/
|   |   |-- foundation.alerts.js
|   |   |-- ...
|   |   |-- foundation.js
|   |   |-- ...
|   |   `-- foundation.topbar.js
|   `-- vendor/
|       |-- custom.modernizr.js
|       |-- jquery.js
|       `-- zepto.js
|-- robots.txt
`-- stylesheets/
    `-- app.css

Next
Setup Git repository for project

Initialize new git repository

$ git init .
Console output
Initialized empty Git repository in ...

Instruct git to ignore generated files

$ cat > .gitignore << LINES
/.awestruct/
/.ruby-*
/.sass-cache/
/_site/
/_tmp/
/Gemfile.lock
LINES
On Windows, run notepad .gitignore, remove all text and paste the content between LINES from above.

Disable Jekyll

Linux / OSX
$ touch .nojekyll
Windows
$ echo "" > .nojekyll

Add all non-ignored files to the git repository

$ git add .

Commit the changes to make the snapshot

$ git commit -m "Initial import of website sources"
Console output
 30 files changed, 18757 insertions(+)
 create mode 100644 .awestruct_ignore
 create mode 100644 .gitignore
 create mode 100644 .nojekyll
 create mode 100644 Gemfile
 create mode 100644 Rakefile
 create mode 100644 _config/site.yml
 create mode 100644 _ext/pipeline.rb
 create mode 100644 _layouts/base.html.haml
 create mode 100644 humans.txt
 create mode 100644 index.html.haml
 create mode 100644 javascripts/foundation/foundation.alerts.js
 create mode 100644 javascripts/foundation/...
 create mode 100644 javascripts/vendor/custom.modernizr.js
 create mode 100644 javascripts/vendor/jquery.js
 create mode 100644 javascripts/vendor/zepto.js
 create mode 100644 robots.txt
 create mode 100644 stylesheets/_normalize.scss
 create mode 100644 stylesheets/_settings.scss
 create mode 100644 stylesheets/app.scss
Changes are now tracked by git. You can rollback at any time.

Create repository on GitHub

Owner
%USERNAME%
Repository name
writeadapt-%USERNAME%
Description (optional)
An Awestruct demo site
Options
Don’t check "Initialize this repository with a README"

Connect git repository to GitHub remote

$ git remote add origin https://github.com/%USERNAME%/writeadapt-%USERNAME%
$ git push origin master
Replace %USERNAME% with your GitHub username.

Next
Configure website metadata

Configure site identity

_config/site.yml
name: Write__Adapt__
title: WriteAdapt - For People Who Love Content
org: Strategy Media
author: The Octocat
author_url: https://github.com/octocat
base_url: ''
ctx_path: ''

Additional configuration to customize processor

_config/site.yml
# append
interpolate: false (1)
haml:
  :ugly: true (2)
1Disables interpolation of Ruby variable expressions in content (e.g., #{name})
2Disables pretty printing (indentation) of HTML output

Clean and preview site to see changes

$ rake clean preview
The clean step is required since a change to the configuration file, _config/site.yml, does not force pages to be regenerated automatically.

Write in plain text

I do not believe that on-page, in-context editing should be the primary edit mode of a CMS.


Deane Barker

Next
Activate AsciiDoc content

Configure Asciidoctor

_config/site.yml
# append
asciidoctor:
  :safe: safe
  :attributes:
    sitename: WriteAdapt
    base_url: ''
    ctx_path: ''
    idprefix: ''
    idseparator: '-'
    sectanchors: ''
    icons: font

Create a page in AsciiDoc format

about.adoc (NOT about.adoc.txt) in project folder
= About {sitename} (1)
Your Name
:page-layout: base (2)
:showtitle: (3)

[.lead]
{sitename} was founded by {author} during a conference workshop.
It's quickly becoming much bigger than this humble beginning.

This page is written in http://asciidoc.org[AsciiDoc].
It's transformed by http://awestruct.org[Awestruct] and http://asciidoctor.org[Asciidoctor] into a webpage for this static website.
1Becomes main heading on the page
2Specifies the layout to use to frame this content
3Shows the page title as an h1 heading

Add About link to navbar

_layouts/base.html.haml
        %li.divider
          %li
            %a(href="#{site.ctx_path}/about.html") About

Make it Sassy!

Append to stylesheets/app.scss
.paragraph.lead > p {
  @extend %lead;
}

Clean and preview site to see changes

$ rake clean preview

Publish your site

Next
Deploy to GitHub Pages

Commit and push any outstanding changes

$ git commit . -m "Enhancements"
$ git push origin master

Create the publish branch, gh-pages

$ git checkout --orphan gh-pages
$ rm -rf *
$ rm -rf .awestruct* .sass-* .gitignore .gitmodules
$ git rm --cached *
$ echo "GitHub Pages placeholder" > index.html
$ git add index.html .nojekyll
$ git commit -m "Seed publish branch for GitHub Pages"

Push the publish branch

$ git push origin gh-pages
$ git checkout master
By pushing the gh-pages branch, you also activated GitHub Pages to publish your website.
View your website
http://%USERNAME%.github.io/writeadapt-%USERNAME%

Setup the Awestruct GitHub Pages deployer

Append to _config/site.yml
profiles:
  development:
    deploy: nil (1)
  production:
    base_url: http://%USERNAME%.github.io/writeadapt-%USERNAME%
    ctx_path: /writeadapt-%USERNAME%
    asciidoctor:
      :attributes:
        base_url: http://%USERNAME%.github.io/writeadapt-%USERNAME%
        ctx_path: /writeadapt-%USERNAME%
        imagesdir: http://%USERNAME%.github.io/writeadapt-%USERNAME%/images (2)
    deploy:
      host: github_pages
      branch: gh-pages
1nil deploy config forces development as default profile
2imagesdir must be absolute to work around Atom feed bug
Replace %USERNAME% with your GitHub username.

Commit deployer configuration

$ git commit _config/site.yml -m "Add profile for GitHub Pages deployment"
$ git push origin master

Deploy to GitHub Pages

$ rake clean deploy
View your website again
http://%USERNAME%.github.io/writeadapt-%USERNAME%
Your Awestruct-based website is now live, and available worldwide!

Content Write, Read and Chunk

Write once, use anywhere and everywhere

Read in the raw

Write the chunk

chunkvsblob
blob content
Your content in HTML

Next
Markdown to AsciiDoc

Sample files

Download
https://raw.github.com/mojombo/jekyll/master/site/docs/pages.md
Save As
docs/_creating-pages.md
Download
https://raw.github.com/mojombo/jekyll/master/site/docs/posts.md
Save As
docs/_writing-posts.md

Formatting

Markdown
**bold**

*italic*

`literal`

`_posts`
AsciiDoc
*bold*

_italic_

+literal+ (or `literal`)

[path]+_posts+

Document header

Markdown
---
layout: docs
title: Writing posts
prev_section: defining-frontmatter
next_section: creating-pages
permalink: /docs/writing-posts/
---
AsciiDoc
= Writing posts
:page-layout: base
:showtitle:
:prev_section: defining-frontmatter
:next_section: creating-pages

Section titles (optional)

Markdown
## The Posts Folder
AsciiDoc
== The Posts Folder

Common article elements such as call-out warnings…were too complex for the WYSIWYG editor.


Jeff Eaton

[E]ditors tried to duplicate the precise markup. [O]thers tried to duplicate the appearance with the WYSIWYG editor’s tools.


Jeff Eaton

Admonitions

HTML embedded in Markdown
<div class="note">
  <h5>ProTip™: Show line numbers</h5>
  <p>
    You can make code snippets include line-numbers by adding the word
    <code>linenos</code> to the end of the opening highlight tag like
    this: <code>{% raw %}{% highlight ruby linenos %}{% endraw %}</code>
  </p>
</div>
AsciiDoc
[TIP, caption='ProTip(TM)']
.Show line numbers
You can make code snippets include line-numbers by adding the word
`linenos` to the end of the opening highlight tag like this:
`{% raw %}{% highlight ruby linenos %}{% endraw %}`

Relative links

Markdown
[directory structure](../structure)
AsciiDoc
link:../structure[directory structure]

External links

Markdown
[Markdown](http://daringfireball.net/projects/markdown/)
AsciiDoc
http://daringfireball.net/projects/markdown[Markdown]

File links

Markdown
[get the PDF]({% raw %}{{ site.url }}{% endraw %}/assets/mydoc.pdf)
AsciiDoc
link:{ctx_path}/assets/mydoc.pdf[get the PDF]
The location of ctx_path must be set in the Awestruct configuration.

Full example with links

Markdown
As explained on the [directory structure](../structure) page, the `_posts`
folder is where your blog posts will live. These files can be either
[Markdown](http://daringfireball.net/projects/markdown/) or
[Textile](http://textile.sitemonks.com/) formatted text files, and as long as
they have [YAML front-matter](../frontmatter), they will be converted from their
source format into an HTML page that is part of your static site.
AsciiDoc
As explained on the link:../structure[directory structure] page, the `_posts`
folder is where your blog posts will live. These files can be either
http://daringfireball.net/projects/markdown/[Markdown] or
http://textile.sitemonks.com/[Textile] formatted text files, and as long as
they have link:../frontmatter[YAML front-matter], they will be converted from
their source format into an HTML page that is part of your static site.

Images

Markdown
![Helpful screenshot]({% raw %}{{ site.url }}{% endraw %}/assets/screenshot.jpg)
AsciiDoc
image::screenshots.jpg[Helpful screenshot]
The location of imagesdir must be set in the Awestruct configuration.

Smart quotes

Markdown
One of Jekyll’s best aspects is that it is “blog aware”.
AsciiDoc
One of Jekyll's best aspects is that it is ``blog aware''.

Source code

Markdown
{% highlight bash %}
YEAR-MONTH-DAY-title.MARKUP
{% endhighlight %}
AsciiDoc
[source,bash]
YEAR-MONTH-DAY-title.MARKUP

Source code with callouts

Markdown
{% highlight ruby %}
def show
  @widget = Widget(params[:id])
  respond_to {|format| format.html # show.html.erb
  }
end
{% endhighlight %}
AsciiDoc
[source,ruby]
def show
  @widget = Widget(params[:id])
  respond_to {|format| format.html ##<1>
  }
end

<1> show.html.erb

Chunk and Clump

Break your content into types

Clump similar content across your project

Output anyway you need it

Style anyway you like it

Next
Chunk some content

Define excerpt for post

:excerpt: Excerpt of post.
:page-excerpt: {excerpt}

{excerpt}

Use post excerpt

Revise _partials/post.html.haml
  .post-body
    - if page.listing
      %p=page.post.excerpt || summarize(html_to_text(page.post.content), 100)
      %p
        %a.small.secondary.button{:href=>post_url} Read more...
    - else
      =page.post.content

Next
Adding source code to your site

Edit _config/site.yml to configure AsciiDoc source highlighter

asciidoctor:
  :safe: safe
  :attributes:
    sitename: WriteAdapt
    base_url: ''
    ctx_path: ''
    idprefix: ''
    idseparator: '-'
    sectanchors: ''
    icons: font
    source-highlighter: coderay
    coderay-css: style

Add CodeRay gem

Gemfile
# append
gem 'coderay'
Install new gems
$ bundle install

Add source code to page

[source,ruby]
----
require 'asciidoctor'

puts Asciidoctor.render 'Write__Adapt__', :doctype => :inline
----

Write content together

Next
Encourage collaboration

Add sidebar to base layout

_layouts/base.html.haml
  #content.row
    .large-9.columns
      =content
    .large-3.columns
      - if page.source_path.end_with? '.adoc'
        - rel_path = page.relative_source_path
        %h4 Collaborate!
        %ul.button-group
          %li
            %a.small.button(href="#{site.edit_base_url}#{rel_path}")
              Edit
          %li
            %a.small.secondary.button(href="#{site.raw_base_url}#{rel_path}")
              Raw
          %li
            %a.small.secondary.button(href="#{site.log_base_url}#{rel_path}")
              Log
      %h4 Topics
      %ul.square
        - site.posts_tags.each do |tag|
          %li
            %a(href="#{site.ctx_path}#{tag.primary_page.url}")=tag

Define collaborate URLs in site configuration

_config/site.yml
edit_base_url: https://github.com/%USERNAME%/writeadapt-%USERNAME%/edit/master
raw_base_url: https://github.com/%USERNAME%/writeadapt-%USERNAME%/raw/master
log_base_url: https://github.com/%USERNAME%/writeadapt-%USERNAME%/commits/master
pull requestable docs

Publish Like a Hacker!