diff --git a/Makefile b/Makefile
index 8702946..254d174 100644
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,17 @@
BINDIR ?= /usr/local/bin
+MANDIR ?= /usr/local/man
+MANFLAVOR ?= man
install:
@echo Installing the executable to $(BINDIR)
- @mkdir -p $(BINDIR)
- @cp -f bb.sh $(BINDIR)/bb
- @chmod 755 $(BINDIR)/bb
+ @install -D -m 755 bb.sh $(BINDIR)/bb
+ @echo Installing the '$(MANFLAVOR)' man page to $(MANDIR)/man1
+ @install -D -m 644 bb.1.$(MANFLAVOR) $(MANDIR)/man1/bb.1
uninstall:
@echo Removing the executable from $(BINDIR)
@rm -f $(BINDIR)/bb
+ @echo Removing the man page from $(MANDIR)
+ @rm -f $(MANDIR)/man1/bb.1
.PHONY: install uninstall
diff --git a/bb.1.man b/bb.1.man
new file mode 100644
index 0000000..42b4c21
--- /dev/null
+++ b/bb.1.man
@@ -0,0 +1,435 @@
+.\" Automatically generated from an mdoc input file. Do not edit.
+.\" Use mandoc -T man ./bb.1.mdoc > bb.1.man to conver to the old
+.\" (but still actively encouraged) Linux "an" format.
+.TH "BB" "1" "November 7, 2022" "Linux 3.10.0-1160.76.1.el7.x86_64" "General Commands Manual"
+.nh
+.if n .ad l
+.SH "NAME"
+\fBbb\fR
+\- A single bash script to create blogs
+.SH "SYNOPSYS"
+\fBbb\fR
+\fBpost\fR
+[\fB\-html\fR]
+[\fIfilename\fR]
+.PP
+\fBbb\fR
+\fBedit\fR
+[\fB\-n\fR
+|
+\fB\-f\fR]
+\fIfilename\fR
+.PP
+\fBbb\fR
+\fBdelete\fR
+\fIfilename\fR
+.PP
+\fBbb\fR
+\fBrebuild|reset|list\fR
+.PP
+\fBbb\fR
+\fBtags\fR
+[\fB\-n\fR]
+.SH "DESCRIPTION"
+When invoked without arguments or with invalid arguments,
+\fBbb\fR
+will print usage. Before you go any further, you may want to check the CONFIGURATION section.
+.PP
+\fBbb\fR
+\fBpost\fR
+will open your
+\fR$EDITOR\fR
+to author a new post in markdown. if available, else in html directly. Use
+\fBbb\fR
+\fBpost\fR
+\fB\-html\fR
+to start a new post using HTML even when markdown is available. After you
+save and exit your editor, you will be asked if you want to post
+(\(lap\(ra),
+edit
+(\(laE\(ra)
+or keep this for later as a draft
+(\(lad\(ra).
+Posts will be served at
+\fBhttps://tilde.club/~you/blog/\fR
+Specifying a
+\fIfilename\fR
+will pre-load the editor with the contents of that file.
+\fIfilename\fR
+is relative to
+\fI~/public_html/blog/.\fR
+.PP
+\fBbb\fR
+\fBedit\fR
+\fIfilename\fR
+allows you to edit an already published .html or .md file.
+\fIfilename\fR
+is relative to
+\fR~/public_html/blog\fR
+and can be either the .md or .html.
+\fBNever\fR
+manually edit a published .html file, always use this function as it
+keeps internal data and rebuilds the blog.
+Use
+\fB\-n\fR
+to give the file a new name, if the title is changed.
+Use
+\fB\-f\fR
+to edit the full html.
+.PP
+\fBbb\fR
+\fBdelete\fR
+\fIfilename\fR
+will delete a post and rebuild the blog.
+.PP
+\fBbb\fR
+\fBrebuild\fR
+regenerates all pages and posts, preserving the content of the entries.
+.PP
+\fBbb\fR
+\fBreset\fR
+deletes everything. Use with caution and
+\fIbackup everything\fR
+first.
+.PP
+\fBbb\fR
+\fBlist\fR
+lists all posts.
+.PP
+\fBbb\fR
+\fBtags\fR
+lists all tags in alphabetical order.
+\fB\-n\fR
+sorts by number of posts under each tag.
+.SH "ENVIRONMENT"
+The following environment variables are used by
+\fBbb\fR
+:
+.TP 9n
+\fREDITOR\fR
+Tell
+\fBbb\fR
+which editor you want to use to edit your posts.
+.SH "FILES"
+.TP 20n
+\fI~/public_html/blog\fR
+The default path for your production blog folder. Make sure to create this,
+otherwise you will see strange behaviour.
+\fIAll paths are relative to this directory.\fR
+.TP 20n
+\fI.config\fR
+Configuration file overriding the global defaults.
+.TP 20n
+\fIdrafts/\fR
+Folder where you drafts are saved if you choose the
+\(oqd\(cq
+option after exiting your
+\fREDITOR\fR.
+.TP 20n
+\fI.backup.tar.gz\fR
+Backup from before you did something silly.
+.TP 20n
+\fI.yesterday.tar.gz\fR
+A backup from yesterday in case
+\fI.backup.tar.gz\fR
+already includes the silly mistake.
+.SH "CONFIGURATION"
+Global defaults are kept within the
+\fBbb\fR
+sh script itself, in the
+\fBglobal_variables\fR()
+function.
+.PP
+You can create
+\fI~/public_html/blog/.config\fR
+which allows you to set
+\fBbash\fR
+variables which override the global defaults.
+\fINote,\fR
+this is a bash script, so the format is
+.RS 6n
+var="value"
+.RE
+Please do not try to get fancy.
+.SS "General Blog Settings"
+.TP 24n
+global_title
+Blog title
+.TP 24n
+global_description
+The typical subtitle for each blog.
+.TP 24n
+global_url
+The public base URL for this blog.
+.TP 24n
+global_author
+Your name
+.TP 24n
+global_author_url
+You can use your tildehome, Twitter, Facebook, etc. as your
+\(oqglobal_author_url\(cq
+.TP 24n
+global_email
+Your email address.
+.TP 24n
+global_license
+CC by-nc-nd is a good starting point, but you can pick a different license. You can change this to
+\(oq©\(cq
+for Copyright.
+.TP 24n
+global_feedburner
+Set to empty
+(\(oq\(cq)
+if you don't use feedburner, otherwise point it to your URL.
+.TP 24n
+global_twitter_username
+.br
+Set this to your username if you want to use Twitter for comments.
+.TP 24n
+global_twitter_cookieless
+Set this to
+\(oqfalse\(cq
+for a Twitter button with a share count. The cookieless version is just a link. This is to comply to EU GDPR regulations.
+.TP 24n
+global_twitter_search
+Default search page, where tweets more than a week old are hidden.
+.SS "Blog Generated Files Settings"
+.TP 24n
+index_file
+The index page of the blog. Probably a good idea to stick with
+\(oqindex.html\(cq
+.TP 24n
+number_of_index_articles
+How many posts to show on the index page.
+.TP 24n
+archive_index
+Page name of your
+\(lqall posts\(rq
+page.
+.TP 24n
+tags_index
+Page name of your
+\(lqall tags\(rq
+page.
+.TP 24n
+gophermap
+Ignore gophermap?
+.TP 24n
+non_blogpost_files
+A bash array of files that
+\fBbb\fR
+will ignore. Useful for static resources. E.g.
+.RS 30n
+.RE
+.RS 24n
+non_blogpost_files=("news.html" "test.html")
+.RE
+.TP 24n
+blog_feed
+RSS feed file name.
+.TP 24n
+number_of_feed_articles
+.br
+How many posts to put in the RSS feed.
+.TP 24n
+cut_do
+\(lqcut\(rq
+blog entry when putting it to index page. Leave blank for full
+articles in front page, i.e. include only up to first
+\(oq
\(cq
+or
+\(oq----\(cq
+in markdown.
+.TP 24n
+cut_tags
+When cutting, cut also tags? If
+\(oqno\(cq
+, tags will appear in index page for cut articles. If
+\(oqyes\(cq,
+they won't.
+.TP 24n
+cut_line
+regex(7)
+matching the HTML line where to do the cut.
+\fINote\fR
+that the slash is regexp separator so you need to prepend it with backslash
+(\(oq\e\(cq).
+.TP 24n
+save_markdown
+If
+\(oqyes\(cq,
+save markdown file when posting with
+\(oqbb post\(cq
+(and markdown is available).
+.TP 24n
+prefix_tags
+Prefix for tags/categories files. Please make sure no other html file starts with this prefix.
+.TP 24n
+header_file
+.TP 24n
+footer_file
+Personalized header and footer (only if you know what you're doing).
+\fIDO NOT\fR
+name them
+\(oq.header.html\(cq,\(oq.footer.html\(cq
+or they will be overwritten. Leave blank
+("")
+to generate them, which is recommended.
+.TP 24n
+body_begin_file
+Extra content to add just before we open the
+\(oq\(cq
+tag and before the actual blog content.
+.TP 24n
+body_end_file
+Extra content to add just before we close
+\(oq\(cq
+tag (just before
+\(oq\(cq).
+.TP 24n
+css_include
+CSS files to include on every page, e.g.
+.RS 30n
+css_include=('main.css' 'blog.css')
+.RE
+.RS 24n
+Leave blank ("") to use the generated ones.
+.RE
+.TP 24n
+html_exclude
+HTML files to exclude from index, e.g.
+.RS 30n
+html_exclude=('imprint.html' 'aboutme.html')
+.RE
+.SS "Localization and Internationalization"
+.TP 24n
+template_comments
+\(lqComments?\(rq
+(used in twitter link after every post).
+.TP 24n
+template_read_more
+\(lqRead more...\(rq
+(link under cut article on index page).
+.TP 24n
+template_archive
+\(lqView more posts\(rq
+(used on bottom of index page as link to archive).
+.TP 24n
+template_archive_title
+\(lqAll posts\(rq
+(title of archive page).
+.TP 24n
+template_tags_title
+\(lqAll tags\(rq
+.TP 24n
+template_tags_posts
+\(lqposts\(rq
+(on
+\(lqAll tags\(rq
+page, text at the end of each tag line, like
+\(lq2.Music-15posts\(rq)
+.TP 24n
+template_tags_posts_2_4
+.br
+Some slavic languages use a different plural form for 2-4 items.
+.TP 24n
+template_tags_posts_singular
+Word to use for one post.
+.TP 24n
+template_tag_title
+\(lqPosts tagged\(rq
+(text on a title of a page with index of one tag, like
+\(lqMy Blog - Posts tagged \(oqMusic\(cq\(rq)
+.TP 24n
+template_tags_line_header
+\(lqTags:\(rq
+(beginning of line in HTML file with list of all tags for this article)
+.TP 24n
+template_archive_index_page
+\(lqBack to the index page\(rq
+(used on archive page, it is link to blog index)
+.TP 24n
+template_subscribe
+\(lqSubscribe\(rq
+(used on bottom of index page, it is link to RSS feed)
+.TP 24n
+template_subscribe_browser_button
+\(lqSubscribe to this page...\(rq
+(used as text for browser feed button that is embedded to html)
+.TP 24n
+template_twitter_button
+.br
+\(lqTweet\(rq
+(used as twitter text button for posting to twitter)
+.TP 24n
+template_twitter_comment
+Default comment used to prepopulate the form.
+.TP 24n
+date_format
+strftime(3)
+format to use for dates.
+.TP 24n
+date_locale
+locale(1)
+to use for dates.
+.TP 24n
+date_inpost
+\(oqbashblog_timestamp\(cq
+.TP 24n
+convert_filename
+Perform the post title -> filename conversion. Experts only. You may need to tune the locales too. Set to empty ("") for no conversion, which is not recommended. The default filter respects backwards compatibility.
+.TP 24n
+preview_url
+URL where you can view the post while it's being edited. By default, it is
+\(oqglobal_url\(cq\&.
+You can change it to the path on your computer, if you write posts locally, before copying them to the server.
+.SH "EXAMPLES"
+Post a markdown file:
+.RS 6n
+bb post ~/my_new_post.md
+.RE
+then hit
+\(lap\(ra\&.
+.PP
+Continue editing a draft:
+.RS 6n
+bb post drafts/the-title-I-was-thinking-of.md
+.RE
+.SH "SEE ALSO"
+bash(1),
+for a reference on variable assignments.
+.SH "AUTHORS"
+cfenollosa \(la\fIhttps://github.com/cfenollosa\fR\(ra
+.PP
+man page by Vlad Me\[u0219]co \(la\fIalzwded@tilde.club\fR\(ra
+.SH "CAVEATS"
+The tilde.club version imposes that the
+\fIblog\fR
+root directory is
+\fI~/public_html/blog\fR,
+and it will
+cd(1)
+to that directory before doing anything else. This makes all
+\fIpaths\fR
+be relative to that directory.
+.PP
+As a side effect, if the
+\fI~/public_html/blog/\fR
+directory does not exist,
+\fBbb\fR
+will get confused and dump files where you don't expect them. Make sure
+you create that path before running
+\fBbb\fR:
+.RS 6n
+mkdir -p ~/public_html/blog/
+.RE
+.PP
+Post file names might get de-unicoded, so if
+\fBbb\fR
+complains it couldn't find your file, use
+find(1)
+or
+grep(1)
+in
+\fI~/public_html/blog/\fR
+to find them.
diff --git a/bb.1.mdoc b/bb.1.mdoc
new file mode 100644
index 0000000..4bdd335
--- /dev/null
+++ b/bb.1.mdoc
@@ -0,0 +1,429 @@
+.\" Use mandoc -T man ./bb.1.mdoc > bb.1.man to conver to the old
+.\" (but still actively encouraged) Linux "an" format.
+.Dd $Mdocdate$
+.Dt BB 1
+.Os
+.Sh NAME
+.Nm bb
+.Nd A single bash script to create blogs
+.Sh SYNOPSYS
+.Nm
+.Cm post
+.Op Fl html
+.Op Pa filename
+.Pp
+.Nm
+.Cm edit
+.Oo Fl n
+|
+.Fl f
+.Oc
+.Pa filename
+.Pp
+.Nm
+.Cm delete
+.Pa filename
+.Pp
+.Nm
+.Cm rebuild|reset|list
+.Pp
+.Nm
+.Cm tags
+.Op Fl n
+.Sh DESCRIPTION
+When invoked without arguments or with invalid arguments,
+.Nm
+will print usage. Before you go any further, you may want to check the CONFIGURATION section.
+.Pp
+.Nm
+.Cm post
+will open your
+.Ev $EDITOR
+to author a new post in markdown. if available, else in html directly. Use
+.Nm
+.Cm post
+.Fl html
+to start a new post using HTML even when markdown is available. After you
+save and exit your editor, you will be asked if you want to post
+.Sm off
+(
+.Aq p
+),
+.Sm on
+edit
+.Sm off
+(
+.Aq E
+)
+.Sm on
+or keep this for later as a draft
+.Sm off
+(
+.Aq d
+).
+.Sm on
+Posts will be served at
+.Lk https://tilde.club/~you/blog/
+\.
+Specifying a
+.Pa filename
+will pre-load the editor with the contents of that file.
+.Pa filename
+is relative to
+.Pa ~/public_html/blog/.
+.Pp
+.Nm
+.Cm edit
+.Pa filename
+allows you to edit an already published .html or .md file.
+.Pa filename
+is relative to
+.Ev ~/public_html/blog
+and can be either the .md or .html.
+.Sy Never
+manually edit a published .html file, always use this function as it
+keeps internal data and rebuilds the blog.
+Use
+.Fl n
+to give the file a new name, if the title is changed.
+Use
+.Fl f
+to edit the full html.
+.Pp
+.Nm
+.Cm delete
+.Pa filename
+will delete a post and rebuild the blog.
+.Pp
+.Nm
+.Cm rebuild
+regenerates all pages and posts, preserving the content of the entries.
+.Pp
+.Nm
+.Cm reset
+deletes everything. Use with caution and
+.Em backup everything
+first.
+.Pp
+.Nm
+.Cm list
+lists all posts.
+.Pp
+.Nm
+.Cm tags
+lists all tags in alphabetical order.
+.Fl n
+sorts by number of posts under each tag.
+.Sh ENVIRONMENT
+The following environment variables are used by
+.Nm
+:
+.Bl -tag -width EDITORX
+.It Ev EDITOR
+Tell
+.Nm
+which editor you want to use to edit your posts.
+.Sh FILES
+.Bl -tag -width x/public_html/blog
+.It Pa ~/public_html/blog
+The default path for your production blog folder. Make sure to create this,
+otherwise you will see strange behaviour.
+.Em All paths are relative to this directory.
+.It Pa .config
+Configuration file overriding the global defaults.
+.Pp
+.It Pa drafts/
+Folder where you drafts are saved if you choose the
+.Sq d
+option after exiting your
+.Ev EDITOR .
+.It Pa .backup.tar.gz
+Backup from before you did something silly.
+.It Pa .yesterday.tar.gz
+A backup from yesterday in case
+.Pa .backup.tar.gz
+already includes the silly mistake.
+.El
+.Sh CONFIGURATION
+Global defaults are kept within the
+.Nm
+sh script itself, in the
+.Fn global_variables
+function.
+.Pp
+You can create
+.Pa ~/public_html/blog/.config
+which allows you to set
+.Sy bash
+variables which override the global defaults.
+.Em Note,
+this is a bash script, so the format is
+.Dl var="value"
+Please do not try to get fancy.
+.Pp
+.Ss General Blog Settings
+.Bl -tag -width xxxxxxxxxxxxxxxxxxxxxx
+.It global_title
+Blog title
+.It global_description
+The typical subtitle for each blog.
+.It global_url
+The public base URL for this blog.
+.It global_author
+Your name
+.It global_author_url
+You can use your tildehome, Twitter, Facebook, etc. as your
+.Sq global_author_url
+.It global_email
+Your email address.
+.It global_license
+CC by-nc-nd is a good starting point, but you can pick a different license. You can change this to
+.Ql ©
+for Copyright.
+.It global_feedburner
+Set to empty
+.Sm off
+(
+.Ql ""
+)
+.Sm on
+if you don't use feedburner, otherwise point it to your URL.
+.It global_twitter_username
+Set this to your username if you want to use Twitter for comments.
+.It global_twitter_cookieless
+Set this to
+.Ql false
+for a Twitter button with a share count. The cookieless version is just a link. This is to comply to EU GDPR regulations.
+.It global_twitter_search
+Default search page, where tweets more than a week old are hidden.
+.El
+.Pp
+.Ss Blog Generated Files Settings
+.Bl -tag -width xxxxxxxxxxxxxxxxxxxxxx
+.It index_file
+The index page of the blog. Probably a good idea to stick with
+.Ql index.html
+.It number_of_index_articles
+How many posts to show on the index page.
+.It archive_index
+Page name of your
+.Dq all posts
+page.
+.It tags_index
+Page name of your
+.Dq all tags
+page.
+.It gophermap
+Ignore gophermap?
+.It non_blogpost_files
+A bash array of files that
+.Nm
+will ignore. Useful for static resources. E.g.
+.Dl
+non_blogpost_files=("news.html" "test.html")
+.It blog_feed
+RSS feed file name.
+.It number_of_feed_articles
+How many posts to put in the RSS feed.
+.It cut_do
+.Dq cut
+blog entry when putting it to index page. Leave blank for full
+articles in front page, i.e. include only up to first
+.Ql
+or
+.Ql ----
+in markdown.
+.It cut_tags
+When cutting, cut also tags? If
+.Ql no
+, tags will appear in index page for cut articles. If
+.Sm off
+.Ql yes
+,
+.Sm on
+they won't.
+.It cut_line
+.Xr regex 7
+matching the HTML line where to do the cut.
+.Em Note
+that the slash is regexp separator so you need to prepend it with backslash
+.Sm off
+(
+.Ql \e
+).
+.Sm on
+.It save_markdown
+If
+.Sm off
+.Ql yes
+,
+.Sm on
+save markdown file when posting with
+.Ql bb post
+(and markdown is available).
+.It prefix_tags
+Prefix for tags/categories files. Please make sure no other html file starts with this prefix.
+.It header_file
+.It footer_file
+Personalized header and footer (only if you know what you're doing).
+.Em DO NOT
+name them
+.Sm off
+.Ql .header.html
+,
+.Ql .footer.html
+.Sm on
+or they will be overwritten. Leave blank
+("")
+to generate them, which is recommended.
+.It body_begin_file
+Extra content to add just before we open the
+.Ql
+tag and before the actual blog content.
+.It body_end_file
+Extra content to add just before we close
+.Ql
+tag (just before
+.Sm off
+.Ql
+).
+.Sm on
+.It css_include
+CSS files to include on every page, e.g.
+.Dl css_include=('main.css' 'blog.css')
+Leave blank ("") to use the generated ones.
+.It html_exclude
+HTML files to exclude from index, e.g.
+.Dl html_exclude=('imprint.html' 'aboutme.html')
+.El
+.Pp
+.Ss Localization and Internationalization
+.Bl -tag -width xxxxxxxxxxxxxxxxxxxxxx
+.It template_comments
+.Dq Comments?
+(used in twitter link after every post).
+.It template_read_more
+.Dq Read more...
+(link under cut article on index page).
+.It template_archive
+.Dq View more posts
+(used on bottom of index page as link to archive).
+.It template_archive_title
+.Dq All posts
+(title of archive page).
+.It template_tags_title
+.Dq All tags
+.It template_tags_posts
+.Dq posts
+(on
+.Dq All tags
+page, text at the end of each tag line, like
+.Sm off
+.Dq 2. Music - 15 posts
+)
+.Sm on
+.It template_tags_posts_2_4
+Some slavic languages use a different plural form for 2-4 items.
+.It template_tags_posts_singular
+Word to use for one post.
+.It template_tag_title
+.Dq Posts tagged
+(text on a title of a page with index of one tag, like
+.Sm off
+.Do "My Blog - Posts tagged "
+.Sq Music
+.Dc
+)
+.Sm on
+.It template_tags_line_header
+.Dq Tags:
+(beginning of line in HTML file with list of all tags for this article)
+.It template_archive_index_page
+.Dq Back to the index page
+(used on archive page, it is link to blog index)
+.It template_subscribe
+.Dq Subscribe
+(used on bottom of index page, it is link to RSS feed)
+.It template_subscribe_browser_button
+.Dq Subscribe to this page...
+(used as text for browser feed button that is embedded to html)
+.It template_twitter_button
+.Dq Tweet
+(used as twitter text button for posting to twitter)
+.It template_twitter_comment
+Default comment used to prepopulate the form.
+.It date_format
+.Xr strftime 3
+format to use for dates.
+.It date_locale
+.Xr locale 1
+to use for dates.
+.It date_inpost
+.Ql bashblog_timestamp
+.It convert_filename
+Perform the post title -> filename conversion. Experts only. You may need to tune the locales too. Set to empty ("") for no conversion, which is not recommended. The default filter respects backwards compatibility.
+.It preview_url
+URL where you can view the post while it's being edited. By default, it is
+.Sm off
+.Ql global_url
+\&.
+.Sm on
+You can change it to the path on your computer, if you write posts locally, before copying them to the server.
+.El
+.Sh EXAMPLES
+Post a markdown file:
+.Dl bb post ~/my_new_post.md
+then hit
+.Sm off
+.Aq p
+\&.
+.Sm on
+.Pp
+Continue editing a draft:
+.Dl bb post drafts/the-title-I-was-thinking-of.md
+.Sh SEE ALSO
+.Sm off
+.Xr bash 1
+,
+.Sm on
+for a reference on variable assignments.
+.Sh AUTHORS
+.An cfenollosa Aq Pa https://github.com/cfenollosa
+.Pp
+.An man page by Vlad Meșco Aq Pa alzwded@tilde.club
+.Sh CAVEATS
+The tilde.club version imposes that the
+.Pa blog
+root directory is
+.Sm off
+.Pa ~/public_html/blog
+,
+.Sm on
+and it will
+.Xr cd 1
+to that directory before doing anything else. This makes all
+.Pa paths
+be relative to that directory.
+.Pp
+As a side effect, if the
+.Pa ~/public_html/blog/
+directory does not exist,
+.Nm
+will get confused and dump files where you don't expect them. Make sure
+you create that path before running
+.Sm off
+.Nm
+:
+.Sm on
+.Dl mkdir -p ~/public_html/blog/
+.Pp
+Post file names might get de-unicoded, so if
+.Nm
+complains it couldn't find your file, use
+.Xr find 1
+or
+.Xr grep 1
+in
+.Pa ~/public_html/blog/
+to find them.
+.\" .Sh BUGS