diff --git a/.gitignore b/.gitignore
index 1fcb152..5a1588d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
out
+draft
diff --git a/README.md b/README.md
index 1d8190a..32b24f2 100644
--- a/README.md
+++ b/README.md
@@ -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`
diff --git a/baker b/baker
index bf1f5a3..3289d9f 100755
--- a/baker
+++ b/baker
@@ -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:=
==tagName==}"
+}
#
# helper
@@ -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|-*$||'
}
#
@@ -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
@@ -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"
@@ -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 ...
diff --git a/layout/post.md b/layout/post.md
index 23f19d9..a098a65 100644
--- a/layout/post.md
+++ b/layout/post.md
@@ -12,6 +12,8 @@
@@ -22,6 +24,14 @@
{{ content }}
+@if tags
+
+@end
+