Brief
Brief is a tool for building applications on top of collections of documents written in markdown.
Brief lets you define models very similar to how you would in ActiveRecord and Rails, but instead of rows in a database you are going to be working with files in a folder.
Getting Started
gem install brief
brief --help
Hypothetical Example
brief init my-cookbook
cd my-cookbook
brief generate model Recipe # View the DOCUMENTATION for what you can do with a model
brief write recipe # => opens up your $EDITOR with an example recipe
Brief treats each markdown file as an active record style model object. It treats a folder of markdown files like a database.
How does it work?
Brief takes a markdown file which looks like:
---
type: post
status: active
---
# An introduction to brief
## Stop writing dead documents
Brief is a tool which lets you define different patterns of markdown
headings (h1,h2,h3 etc). This lets you work with collections of your
writings, and treat each document as a database.
And turns it into data, not only using the metadata up top, but also the information contained in the structure of the document itself. The headings, subheadings, pretty much anything you could query from the HTML using CSS can be turned into key value pairs that you can work with and build applications on top of.
With your enhanced writing, you can do things like:
# Find all the posts which are active:
posts = briefcase.posts.where(status:"published")
# Get their titles, and subheadings:
posts.map(&:title) #=>['An introduction to brief']
posts.map(&:subheading) #=>['Stop writing dead documents']
# Publish the post
posts.first.publish()
# Email the drafts to your editor
posts.where(status:"draft").each &:mail_to_editors
From the Command line we can:
brief publish posts
brief write post #=> Opens your editor
This type of interactivity is made possible by the Brief::Model
Documents as models
define "Post" do
do
status
end
content do
title "h1:first-of-type"
subheading "h2:first-of-type"
sample "p:first-of-type"
end
actions do
def publish
update_attributes(status: "published")
end
end
end
CLI Tool
Brief gives you a CLI called brief
This lets you run some general commands, but also gives you an intelligent interface to work with your models. In the above example, we defined some actions.
This will be available in the CLI:
brief publish posts ./docs/posts/*.md
This will find all of the matching documents, turn them into Post
models, and then run the publish method on them. You can make your
models as advanced as you want:
define "Post" do
actions do
def submit
update_attributes(status:"submitted to editors")
mailer.send(:to => "[email protected]", :subject => "Please review: #{ self.title }")
end
end
end
YAML Frontmatter
Each markdown document can contain YAML frontmatter. This data will be available and associated with each document or model, and will also let you query, filter, and sort your documents.
CSS Structure Definition
Since markdown renders into HTML, and HTML Documents can be queried using CSS selectors, we use CSS selectors in our model definition DSL so that we can isolate certain parts of the document, and use the content it contains as metadata.
A real world example:
content do
title "h1:first-of-type"
define_section "User Stories" do
each("h2").has(:title => "h2",
:paragraph => "p:first-of-type",
:components => "p:first-of-type strong"
)
each("h2").is_a :user_story
end
end
This lets me turn a markdown file like:
---
title: Epic Example
status: published
---
# Epic Example
# User Stories
## A user wants to do something
As a **User** I would like to **Do this** so that I can **succeed**
## A user wants to do something else
As a **User** I would like to **Do this** so that I can **succeed**
into:
{
title: "Epic Example",
status: "published",
type: "epic",
user_stories:[{
title: "A user wants to do something",
paragraph: "As a user I would like to do something so that I can succeed",
goal: "I can succeed",
persona: "user",
behavior: "do something"
},{
title: "A user wants to do something else",
paragraph: "As a user I would like to do something else so that I can succeed"
}]
}
And we can even go in the other direction.