Over the years, a lot of little gadgets were created and now they were looking for a place to live in harmony. For some, github would be right; some would live in a blogspace; but some just needed to move and wriggle and play hide and seek. Thus emerged this place, as a nurturing zoo for them all.

How it works

There is no database. The path elements you see in the url are actual directories. For example, this directory contains an index.md that is translated to this index.html using markdown. In addition, menus are generated on the left and items (listed in items.md) are put in a drawer on the right.

Licenses

This site uses fonts with different licenses:

Molot

OpenSans

Space Mono

Simonetta

jan 2016-06-17, updated 2018-04-04
index.md
Over the years, a lot of little gadgets were created and now they
were looking for a place to live in harmony.  For some,
[github](http://github.com/tylus) would be right; some would live in a blogspace;
but some just needed to move and wriggle and play hide and seek.  Thus
emerged this place, as a nurturing zoo for them all.

How it works
------------

There is no database.  The path elements you see in the url are actual
directories.  For example, this directory contains an `index.md` that
is translated to this `index.html` using
[markdown](https://daringfireball.net/projects/markdown/syntax).  In
addition, menus are generated on the left and items (listed in
`items.md`) are put in a drawer on the right.

Licenses
--------

This site uses fonts with different licenses:

[<font style="font-family:block">Molot</font>](http://www.1001fonts.com/molot-font.html)

[<font style="font-family:sans">OpenSans</font>](https://www.google.com/fonts/specimen/Open+Sans)

[<font style="font-family:mono">Space Mono</font>](https://fonts.google.com/specimen/Space+Mono)

[<font style="font-family:flourish">Simonetta</font>](https://fonts.google.com/specimen/Simonetta)

<div class="sign">jan 2016-06-17, updated 2018-04-04</div>
items.md
index.md
items.md
../../bin/make-index.py
../../bin/make-drawer.py
../../bin/make-index.py
#!/usr/bin/python

import os
import os.path
import sys
import subprocess
import hashlib

me, path, target = sys.argv

stack = []
root = os.getcwd()

ignore_paths = ['.']
ignore_dirs = ['bin', 'css', 'js', 'node_modules', 't', 'static']

def writeMenuFragment():
    with open(os.path.join(root, path, ".menu"), "w") as out:
        out.write('    <div class="menu">\n')
        for name in getDirsInOrder(path):
            dirpath = os.path.join(path, name)
            if (os.path.isdir(dirpath)
                and not name.startswith(".")):
                out.write('      <div class="menuentry%s">%s</div>\n'
                          % (tagIfStaging(dirpath),
                             renderMenuTitle(name)))
                pass
            continue
        out.write("""      <div class="spacer"></div>
      <div class="logo"><a href=".">rg</a></div>
""")

        out.write('    </div>\n')

def tagIfStaging(name):
    if os.path.isfile(os.path.join(name, '.staging')):
        addToRobotsTxt(name)
        return ' staging'
    return ''

def addToRobotsTxt(name):
    with open('.stages', 'a') as stages:
        print >> stages, name

def renderMenuTitle(name):
    if '+' in name:
        date, title = name.split('+')
        return ('<a href="%s/" class="blogtitle">%s</a><br/>'
                '<a href="%s/" class="blogdate">%s</a>'
                % (name, title.replace("_", "&nbsp;"),
                   name, date))
    return '<a href="%s/">%s</a>' % (name, name.replace("_", "&nbsp;"))

def writeIndexPage():
    with open(os.path.join(root, target), "w") as out:
        pathsegments = paths(path)
        out.write("""<!DOCTYPE html>
<html>
  <head>
    <title>%(title)s | rechengilde</title>
    <meta charset="utf-8" />
    <meta name="theme-color" content="#ffe" />
    <link rel="stylesheet" href="%(updir)scss/rg.css?%(rgcsshash)s"/>
    <script type="text/javascript" src="%(updir)sjs/jquery-2.2.4.min.js"></script>
    <script type="text/javascript" src="%(updir)sjs/rg.js?%(rgjshash)s"></script>
  </head>
  <body>
""" % {'updir': updir(len(pathsegments) - 1),
       'title': makeTitle(path),
       'rgcsshash': hashFile('css/rg.css'),
       'rgjshash': hashFile('js/rg.js')})
        for depth, prefix, selected in zip(range(len(pathsegments)),
                                                 pathsegments,
                                                 pathsegments[1:]+['-']):
            out.write(renderMenuFragment(os.path.join(prefix, ".menu"),
                                         selected,
                                         len(pathsegments) - depth - 1))
        renderContent(out)
        renderDrawer(out)
        out.write("""  </body>
</html>""")

def getDirsInOrder(path):
    dirs = [(dir, path) for dir in os.listdir(path)
            if dir not in ignore_dirs]
    dirs.sort(key=getDirKey,
              reverse=os.path.isfile(os.path.join(path, '.desc')))
    return [k for k, v in dirs]

def getDirKey(t):
    sortKeyFile = os.path.join(t[1], t[0], '.sortkey')
    if os.path.isfile(sortKeyFile):
        with open(sortKeyFile) as sortkey:
            return sortkey.read()
    return t[0]

def paths(path):
    paths = [path for path in ("/"+path.strip("/")).split("/")
             if path not in ignore_paths]
    return ["/".join(paths[1:i+1]) for i in range(len(paths))]

def renderMenuFragment(filename, selectedItem, levels):
    selectedItem = os.path.basename(selectedItem)
    menutext = ''
    with open(filename) as levelmenu:
        menutext = levelmenu.read()
        menutext = menutext.replace('"><a href="' + selectedItem,
                                    ' selected"><a href="' + selectedItem)
        menutext = menutext.replace('href="',
                                    'href="' + updir(levels))
    return menutext

def renderContent(out):
    content = ""
    md = path + "/index.md"
    if os.path.isfile(md):
        content = subprocess.check_output(["markdown", md])

        # external links open in a new tab or window
        content = content.replace('<a href="http',
                                  '<a target="_blank" href="http')

        # for some reason, "markdown" wraps multiline-codeblocks
        # not only in a "pre", but also in a "code" environment.
        content = content.replace('<pre><code>', '<pre>')
        content = content.replace('</code></pre>', '</pre>')

        # wrap all in a div that marks the main panel
        content = """    <div class="content" tabindex="0">
%s
    </div>
""" % content

    raw = path + "/index.raw.html"
    if os.path.isfile(raw):
        with open(raw) as rawfile:
            content = rawfile.read()
        pass

    out.write(content)
    return

def renderDrawer(out):
    raw = path + "/.drawer"
    if os.path.isfile(raw):
        with open(raw) as rawfile:
            out.write(rawfile.read())

def makeTitle(path):
    return path.replace("/", ": ").replace("_", " ")

def updir(levels):
    return '../' * levels

def hashFile(filename):
    m = hashlib.md5()
    with open(filename) as f:
        m.update(f.read())
    return m.hexdigest()[:6]

if __name__ == "__main__":
    writeMenuFragment()
    writeIndexPage()
../../bin/make-drawer.py
#!/usr/bin/python

import sys
import subprocess
import os.path

itemsfilename, drawerfilename = sys.argv[1:]
items = open(itemsfilename)
drawer = open(drawerfilename, "w")
deps = open(drawerfilename + ".d", "w")

special = {
    '.coffee': ['-S', 'py'],
    '.md': ['-S', 'txt']
}

def render(item):
    args = ["highlight", "-f", "--enclose-pre"]
    ext = os.path.splitext(item)[1]
    if ext in special:
        args += special[ext]
    args.append(item)
    return subprocess.check_output(args)

drawer.write("""    <div class="drawer">
      <input type="checkbox" name="showdrawer" id="showdrawer"/>
      <label for="showdrawer" accesskey="H" title="AccessKey-H">How?</label>
      <div class="items">
""")
deps.write(drawerfilename + ":");

for item in items.readlines():
    item = item.strip()
    deps.write(' ' + item.replace(r' ', r'\ '))

    drawer.write("""        <div>
          <div class="itemtitle">%s</div>
%s
        </div>
""" % (item, render(item)))

drawer.write("""        <div class="rest">:</div>
      </div>
    </div>
""");
deps.write("\n")
: