Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f6efa94
Baker now creates a Draft dir and generate post for drafted post.
Flyounet Nov 20, 2015
6e973bf
For people like me (who's speaking french), accent are important.
Flyounet Nov 20, 2015
602ace3
Starting to implement a sort of Prev/Next button for each post.
Flyounet Nov 20, 2015
73cb377
Merge branch 'draftdir' into prevnextpost
Flyounet Nov 20, 2015
f76bb18
When posts are baked, they now points to older are newer posts.
Flyounet Nov 20, 2015
addea7c
Baker now list all posts with their status
Flyounet Nov 20, 2015
3d7a671
Baker now is able to easily change the status of a post
Flyounet Nov 20, 2015
1e76374
Adding help for toggle
Flyounet Nov 20, 2015
c523dc0
Changed tog by toggle in the switch to follow help
Flyounet Nov 20, 2015
e4b8a04
Adding info about toggle in the README
Flyounet Nov 20, 2015
cf64ab2
Typo error in the README
Flyounet Nov 20, 2015
64341d8
The actions : post, list and toggle are now functions. It will be eas…
Flyounet Nov 20, 2015
5a5c09e
The actione : bake is now a function post_bake.
Flyounet Nov 20, 2015
dff34d8
Configuration is now in a function. When i'll have finishing to put e…
Flyounet Nov 20, 2015
f17969f
Merge branch 'functionalize' into dev
Flyounet Nov 20, 2015
f603fa8
Define the base name for categories
Flyounet Nov 20, 2015
2bba45b
It almost works \o/. Categories are generated.
Flyounet Nov 20, 2015
4ae2b8e
Categories are well generated in the post now (updated layout and pos…
Flyounet Nov 20, 2015
2e81255
Starting to rename categories by tags. It's the name the original aut…
Flyounet Nov 20, 2015
f4c121a
All categories reference should have been removed and replaced with t…
Flyounet Nov 20, 2015
b941131
Indexes for tags are generated.
Flyounet Nov 20, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
out
draft
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

1. Give it a title: `./baker post I love pizza so much!` This command will create a markdown file that has the slug `i-love-pizza-so-much` in the `post` directory. If the `$EDITOR` environment variable is set, it will open up the post markdown file with the editor.

2. Change `draft` from `true` to `false` to publish the post.
2. Change `draft` from `true` to `false` to publish the post (or use the `./baker toggle id`).

3. Bake all posts: `./baker bake`

Expand Down
279 changes: 219 additions & 60 deletions baker
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,42 @@
#
# config
#

# POST_DIR stores all post markdown files
readonly POST_DIR=post

# OUTPUT_DIR stores all compiled html
readonly OUTPUT_DIR=out

# LAYOUT_DIR stores all layout markdown files
readonly LAYOUT_DIR=layout

# PUBLIC_DIR stores css and static images
readonly PUBLIC_DIR=public

# site
readonly SITE_NAME='a baker blog'
readonly SITE_DESC='written in bash'
readonly DISQUS='bakerbash'

# author
readonly AUTHOR_NAME='baker'
readonly AUTHOR_DESC='a very-experienced bread baker, who also loves planting trees.'
readonly AUTHOR_EMAIL='email@example.org'
readonly AUTHOR_EMAIL_HASH="$(md5sum <<< "$AUTHOR_NAME" | awk '{ print $1 }')"
readonly AUTHOR_TWITTER='twitter'
readonly AUTHOR_GITHUB='github'
config() {
if [ -f "${1:-}" ]; then
. "${1}"
fi
# POST_DIR stores all post markdown files
export POST_DIR="${POST_DIR:=post}"

# OUTPUT_DIR stores all compiled html
export OUTPUT_DIR="${OUTPUT_DIR:=out}"

# DRAFT_DIR stores all compiled html
export DRAFT_DIR="${DRAFT_DIR:=draft}"

# LAYOUT_DIR stores all layout markdown files
export LAYOUT_DIR="${LAYOUT_DIR:=layout}"

# PUBLIC_DIR stores css and static images
export PUBLIC_DIR="${PUBLIC_DIR:=public}"

# site
export SITE_NAME="${SITE_NAME:=a baker blog}"
export SITE_DESC="${SITE_DESC:=written in bash}"
export DISQUS="${DISQUS:=bakerbash}"

# author
export AUTHOR_NAME="${AUTHOR_NAME:=baker}"
export AUTHOR_DESC="${AUTHOR_DESC:=a very-experienced bread baker, who also loves planting trees.}"
export AUTHOR_EMAIL="${AUTHOR_EMAIL:=email@example.org}"
export AUTHOR_EMAIL_HASH="${AUTHOR_EMAIL_HASH:=$(md5sum <<< "$AUTHOR_NAME" | awk '{ print $1 }')}"
export AUTHOR_TWITTER="${AUTHOR_TWITTER:=twitter}"
export AUTHOR_GITHUB="${AUTHOR_GITHUB:=github}"

# categories
export TAGS_BASELIST="${TAGS_BASELIST:=mylife,internet,baker}"
export TAGS_LINK="${TAGS_LINK:=<li><a href='index_==tagNameSlugged==.html' title='jump to tag'><i class='fa fa-tag'></i>&nbsp;==tagName==</a></li>}"
}

#
# helper
Expand Down Expand Up @@ -56,7 +67,7 @@ body() {

# slug creates a friendly URL like 'hello-world'
slug() {
tr -cs '[:alnum:]\n' - | tr '[:upper:]' '[:lower:]' | sed 's|^-*||;s|-*$||'
iconv -f utf8 -t ascii//TRANSLIT | tr -cs '[:alnum:]\n' - | tr '[:upper:]' '[:lower:]' | sed 's|^-*||;s|-*$||'
}

#
Expand Down Expand Up @@ -147,6 +158,8 @@ render_if() {
local lines
local line
readarray -t lines
# The following regexp should be a little amended to allow more than one space|tab
# between the @if and id (AND after)
[[ "${lines[0]}" =~ ^@if\ ('!')?($VAR_ID)$ ]] || return 1

# skip render on undefined_var or !defined_var
Expand All @@ -155,7 +168,6 @@ render_if() {
else
[[ "${BASH_REMATCH[1]}" == '!' ]] || return 0
fi

# recursively render the inner block
for line in "${lines[@]:1:${#lines[@]}-2}"; do
echo "$line"
Expand Down Expand Up @@ -263,66 +275,213 @@ render_file() {
echo "$content"
}

#
# usage
#
usage() {
cat <<-EOF
baker
post [title] draft a post
bake ship all posts
EOF
exit 1
# post_toggle toggles the status of a post (either use ID or post name)
post_toggle() {
local _fname=''
if [ -z "${1:-}" ]; then
usage
elif [ -z "${1//[0-9]/}" ]; then
readarray -t posts < <(find "$POST_DIR" -name '*.md' | sort -r)
if [ ${1} -lt ${#posts[@]} ]; then
_fname="${posts[${1}]}"
fi
elif [ -f "${POST_DIR}/${1}" -o -f "${POST_DIR}/${1}.md" ]; then
_fname="${POST_DIR}/${1//\.md/}.md"
fi
if [ -z "${_fname}" ]; then
echo "This post doesn't exist"
exit 1
fi
if [ "$(header draft < "${_fname}")" == 'false' ]; then
sed -i -e 's;^[[:space:]]*draft:[[:space:]]*false[[:space:]]*$;draft: true;g' "${_fname}"
else
sed -i -e 's;^[[:space:]]*draft:[[:space:]]*.*[[:space:]]*$;draft: false;g' "${_fname}"
fi
}

(( $# == 0 )) && usage
# post_list list the id title and status of posts
post_list() {
local idx=0
readarray -t posts < <(find "$POST_DIR" -name '*.md' | sort -r)
(
echo "id title status"
for post in "${posts[@]}"; do
id="$(basename "$post" .md)"
# skip drafts
if [ "$(header draft < "$post")" == 'false' ]; then
echo "${idx} $id [Published]"
else
echo "${idx} $id [Draft]"
fi
((idx++))
done
) | column -t
}

case "$1" in
bake)
# post_post creates a post (in the POST_DIR) with the minimum information
post_post() {
readonly title="${@}"
[[ "$title" ]] || usage

mkdir -p "$POST_DIR" || ( echo "Can't create '$POST_DIR'" >&2; exit 1 )
readonly post_file="$POST_DIR/$(date +%Y-%m-%d)-$(slug <<< "$title").md"
cat > "$post_file" <<-EOF
---
title: $title
date: $(date -u +%FT%TZ)
tags: ${TAGS_BASELIST}
layout: post
draft: true
summary:
---
EOF

echo "$post_file"
[[ "$EDITOR" ]] && $EDITOR "$post_file"
}

# post_bake it's where the magic start
post_bake() {
rm -rf "$DRAFT_DIR"
mkdir -p "$DRAFT_DIR"
rm -rf "$OUTPUT_DIR"
mkdir -p "$OUTPUT_DIR"

[[ -d "$POST_DIR" ]] || usage
[[ -d "$PUBLIC_DIR" ]] && cp -r "$PUBLIC_DIR"/. "$OUTPUT_DIR"
[[ -d "$PUBLIC_DIR" ]] && cp -r "$PUBLIC_DIR"/. "$DRAFT_DIR"
touch "$DRAFT_DIR/index.html"

readarray -t posts < <(find "$POST_DIR" -name '*.md' | sort -r)

echo "Rendering Posts..." >&2
idx=0
id_all=0
_allTags=''
time for post in "${posts[@]}"; do
idx_prev=1;idx_next=1
id="$(basename "$post" .md)"
# skip drafts
[[ "$(header draft < "$post")" == false ]] || continue
if [ "$(header draft < "$post")" != false ]; then
(( id_all++ ))
POST_PREV='index.html';POST_NEXT='index.html'; render_file "$post" > "$DRAFT_DIR/$id.html"; continue;
fi
if [ ${idx} -eq 0 ]; then # It's the first post, so the newer one is index
id_prev=0
else # search for the previous post not draft
while [ -f "${posts[$((id_all-idx_prev))]}" -a "$(header draft < "${posts[$((id_all-idx_prev))]}" 2>/dev/null)" != false ]; do
(( idx_prev++ ))
if [ ${idx_prev} -gt ${id_all} ]; then idx_prev=${id_all}; break; fi
done 2>/dev/null
fi
# look for the next older post not draft
while [ -f "${posts[$((id_all+idx_next))]}" -a "$(header draft < "${posts[$((id_all+idx_next))]}" 2>/dev/null)" != false ]; do
(( idx_next++ ))
done 2>/dev/null

echo "$id"
if [ ${idx} -eq 0 -o $((idx_all-idx_prev)) -eq 0 -a ${id_all} -eq 0 ]; then
POST_PREV="index.html"
else
POST_PREV="$( basename "${posts[$((id_all-idx_prev))]}" )"
POST_PREV="${POST_PREV%*.md}.html"
fi
POST_NEXT="$( basename "${posts[$((id_all+idx_next))]}" )"
[[ -z "${POST_PREV:=}" ]] && POST_PREV='index.html'
[[ -z "${POST_NEXT:=}" ]] && POST_NEXT='index.md'
POST_NEXT="${POST_NEXT%*.md}.html"
# look for the tags
if [ ${__c:=0} -eq 0 ]; then # When implemented the -c will avoid tags generation
local _tag=''; TAGSLIST=''
tags="$(header tags < "$post")"
if [ ! -z "${tags}" ]; then
while read _tag; do
TAGSLIST="${TAGSLIST}${TAGS_LINK//==tagNameSlugged==/$(slug <<< "${_tag}")}"
TAGSLIST="${TAGSLIST//==tagName==/${_tag}}"
_allTags="${_allTags//${_tag},/}${_tag},"
done <<< "$(echo -e "${tags//,/\\n}")"
fi
else
unset TAGSLIST
unset tags
fi
# Render the post
echo "$idx - $idx_next - $id [Prev:${POST_PREV}][Next:${POST_NEXT}] [Tags:${tags}]"
render_file "$post" > "$OUTPUT_DIR/$id.html" &
declare "posts_${idx}_id"="$id"
export_headers "$post" "posts_${idx}_"
POST_PREV="$id.html"
(( id_all++ ))
(( idx++ ))
done

echo "Rendering Index..." >&2
render_file "$LAYOUT_DIR/index.md" > "$OUTPUT_DIR/index.html" &
wait
;;
post)
readonly title="${@:2}"
[[ "$title" ]] || usage
# Generate the indexes for each tags
if [ ${__c:=0} -eq 0 ]; then
echo "Rendering Index for categories..." >&2
while read _tagIdx; do
# It's really important to unset all posts variables
while read a; do unset "${a}"; done <<< "$(compgen -v | grep -E "^posts_[0-9]")"
idx=0
id_all=0
for post in "${posts[@]}"; do
id="$(basename "$post" .md)"
if [ "$(header draft < "$post")" != false ]; then continue; fi
tags="$(header tags < "$post")"
if [ ! -z "${tags}" ]; then
while read _tag; do
if [ "${_tag}" = "${_tagIdx}" ] ; then
declare "posts_${idx}_id"="$id"
export_headers "$post" "posts_${idx}_"
(( idx++ ))
fi
done <<< "$(echo -e "${tags//,/\\n}")"
fi
done
render_file "$LAYOUT_DIR/index.md" > "$OUTPUT_DIR/index_$(slug <<< "${_tagIdx}").html" &
wait
done <<< "$(echo -e "${_allTags//,/\\n}")"
fi
}

mkdir -p "$POST_DIR"
readonly post_file="$POST_DIR/$(date +%Y-%m-%d)-$(slug <<< "$title").md"
cat > "$post_file" <<-EOF
---
title: $title
date: $(date -u +%FT%TZ)
layout: post
draft: true
summary:
---
#
# usage
#
usage() {
cat <<-EOF
baker
post [title] draft a post
bake ship all posts
list list all posts with state
toggle [post] toggle the draft status of a post
EOF
exit 1
}

echo "$post_file"
[[ "$EDITOR" ]] && $EDITOR "$post_file"
(( $# == 0 )) && usage

config
readonly POST_DIR; readonly OUTPUT_DIR; readonly DRAFT_DIR; readonly LAYOUT_DIR; readonly PUBLIC_DIR
readonly SITE_NAME; readonly SITE_DESC
readonly AUTHOR_NAME; readonly AUTHOR_DESC; readonly AUTHOR_EMAIL; readonly AUTHOR_EMAIL_HASH;
readonly AUTHOR_TWITTER; readonly AUTHOR_GITHUB; readonly DISQUS
readonly TAGS_LINK; readonly TAGS_BASELINK

case "$1" in
bake)
post_bake
;;
post)
post_post "${@:2}"
;;
list)
post_list
;;
toggle)
post_toggle "${@:2}"
;;
*)
usage
;;
esac

# TODO : add flags management : -h help, -c no categories, -f configfile, -w workin this directory, -d change la date ...
10 changes: 10 additions & 0 deletions layout/post.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
<nav>
<ul class="nav nav-pills pull-right">
<li class="active"><a href="index.html">Home</a></li>
<li><a href="{{ POST_PREV }}" title="Newer"><i class="fa fa-long-arrow-left fa-2x"></i></a></li>
<li><a href="{{ POST_NEXT }}" title="Older"><i class="fa fa-long-arrow-right fa-2x"></i></a></li>
<li><a href="#author">About</a></li>
</ul>
</nav>
Expand All @@ -22,6 +24,14 @@
{{ content }}
</article>

@if tags
<aside>
<ul class="tags">
{{ TAGSLIST }}
</ul>
</aside>
@end

<footer id="author" class="row">
<section class="col-md-5">
<p class="post-date">Published on <time>{{ date }}</time></p>
Expand Down
1 change: 1 addition & 0 deletions post/2015-06-19-hello-world.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
title: hello world!
date: 2015-06-19T01:01:56Z
tags: baker,internet
layout: post
draft: false
summary: This is your first post.
Expand Down
12 changes: 12 additions & 0 deletions post/2015-11-20-welcome-to-baker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
title: Welcome to Baker!
date: 2015-11-20T11:06:07Z
tags: baker
layout: post
draft: false
summary: This is your second post.
---

With the **Markdown** syntax, expect more readbility. Be prepared to start blogging!

<iframe width="100%" height="166" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/121515363&color=ff5500"></iframe>