November 12, 2013
Greetings. My pseudonym is Ypnose.
Some people already know me (at least I hope so), I try to be often involved in FOSS projects. I also write articles on my french blog, since 2011 (it was discontinued for many reasons). This is my 2nd weblog. I'll talk about shell or related hacks. I plan to share some of my tools & configs as well.
Actually, I'm in love with *ksh shells (and not necessarily
because I started serious programming on
Compared to the others shells I tried, they do everything faster and
more easily. Many persons use a shell everyday, only in interactive
mode. They want a fancy prompt with colors, dozens of Unicode
PWD, date(1) or
clock. Personally, I chose my shell according to its "power". For my
sake, script usage is much more important. Before *ksh, I played a
lot with POSIX shell.
I decided to create my own static website
because I was unable to find something which fits my
special needs. We already have similar softwares,
Hakyll. Unfortunately, I
wanted a tool in pure shell (here mksh(1))
+ others UNIX utilities,
like find(1) or awk(1).
I have no limits (except my own limits), I can do everything I want
with my lines. That's why wswsh
([w]eb [s]ucks [w]ithout
[sh]ell) is born. It's designed as I wish.
SHELL is underestimated, because it
seems to be archaic, simplistic, dirty or designed for easy tasks. I
think this is stupid, it's a strong tool. I do difficult/advanced
tasks with it and I'm happy so far.
I'll try to explain you how wswsh works (reading my comments is useful too).
We are in a directory (which will be your brand new website) named "ITOOGUD", with the following files. It composes the minimal dependencies.
. ├── includes │ └── layout ├── wswsh └── wswsh.conf.default
includes contains website parts (layouts, header or
wswsh is the main part of the script and
wswsh.conf.default is the example config file. You have
to rename it to
wswsh.conf It contains the website
options. Read the comments inside for more information.
Now, the show begins...
Make a directory called
src. In this example, we
have a basic structure, with 5 folders and 4 files. As you can see,
some files have an unknown extension
.wshtml. This is
a generic extension (I can distinguish my posts without having a
headache), it symbolizes articles written in HTML fragments
.wtfhtml is OK too). Moreover, try to
.html for your articles.
. ├── includes │ └── layout ├── src │ ├── css │ │ └── style.css │ ├── blog │ │ └── index.wshtml │ ├── me │ │ └── john_doe.wshtml │ └── foo │ └── baz │ └── trololol.wshtml ├── wswsh └── wswsh.conf
./wswsh "$PWD". First of all, the script
will reproduce exactly the directory structure,
in a new folder
recursively analyzes the sources located to
dest ├── css ├── blog ├── me └── foo └── baz
Then, find(1) "scans" those sources
and "records" files with the chosen extension (here
.wshtml). For example, if
WSH_INTERP="ahrf", the interpreter "reads"
the file and its standard output is redirected to a file
$ ahrf my_article > my_new_article. This interpreter
must be placed in your
PATH! Otherwise, the script
concatenate the file(s) (+
page_footer functions) to a new one, in
dest. It does something like
$ cat file1 file2 file3 > new_file. Trivial isn't
dest ├── css │ └── style.css ├── blog │ └── index.html ├── me │ └── john_doe.html └── foo └── baz └── trololol.html
Huhh?... How can you copy this
It's not handled by find(1), right?
Yes, that's true, boy. There is a variable
wswsh.conf to copy the stylesheet into
dest/. This variable can be used to apply tags in
layout as well.
. ├── dest │ └── css │ └── style.css ├── src │ └── css │ └── style.css ├── wswsh └── wswsh.conf
Sometimes, our pages are not dynamically generated, so we do not
need to deal with these files. It's true for static start pages or
menus. In that case, we just desire to copy them, to the
destination. The program has a section (cf
which does the trick, if it finds
*.html. As it was
mentioned above, you shouldn't use
.html for all posts
. ├── src │ ├── start │ │ └── index.html │ └── menu │ └── 2013 │ └── index.html ├── wswsh └── wswsh.conf
Despite all the care, some files are trying to escape us. It
was possible to export those
files, stored in a variable called
FIL but I decided to
remove that possibility. Copying external file(s) shouldn't be done
by the main script. You could do it using a trivial script or via
. ├── src │ ├── blog │ ├── flux.xml │ └── robots.txt ├── wswsh └── wswsh.conf
Testing the website was a bit problematic. I wanted to test the web pages, with a minimal server and I was too lazy to install Nginx / lighttpd (and using them is totally overkill). What a dilemma! I finally decided to grab and compile a tiny C web server called darkhttpd (NOO, it's not PURE shell). Indeed, but it doesn't "violate" my specifications. wswsh is a standalone script and this server isn't part of the script. Since I'm a very detail-oriented person, I like to verify the final result but you don't have to do it.
I won't describe all the possibilities in this article (configs parsing, various interpreters), because it would be very boring. If you read closely my code, I guess it won't be very difficult to understand what it does. I'll add some functionalities later (perhaps). I think I'll add RSS Atom feeds are also supported. However, it won't be "ported" on sh.
The script uses "Modified BSD License".
I hope you were interested by this first article. See ya soon!