ADDED cfg/links Index: cfg/links ================================================================== --- cfg/links +++ cfg/links @@ -0,0 +1,14 @@ + this is just a space-delimited list of main links. the + first part should contain the URL to link to, relative to + the root of the generated site. + + for instance, if you have a file in src/stories/a-story.md, + you would write /src/stories/a-story.html. + + note that URLs cannot contain spaces! also, lines beginning + with a space are treated as comments and are ignored by the + parser. + +/index.html home +/about.html about +/doc/index.html tsunami docs ADDED cfg/sitename Index: cfg/sitename ================================================================== --- cfg/sitename +++ cfg/sitename @@ -0,0 +1,7 @@ + this is the text that is displayed in your header. + the first line is wrapped in
$ln
\n"; + } + } elsif (($ctx == ORDLIST) or + ($ctx == STARLIST)) { + $pg .= "$ln
\n"; + } + } + print $out page $outpath.".html", $pg; + close $in; + close $out; + }, + 'html' => sub { my ($inpath, $outpath) = @_; + print "wrapping html → \e[36m$outpath.html\e[0m"; + open my $in, "<:encoding(UTF-8)", $inpath; + my $file; + { local $/; $file = <$in>; } + close $in; + open my $out, ">:encoding(UTF-8)", $outpath.".html"; + print $out page $outpath.".html", $file; + close $out; + }, + 'raw' => sub { my ($inpath, $outpath) = @_; + print "copying raw → \e[36m$outpath\e[0m"; + open my $in, "<:encoding(UTF-8)", $inpath; + my $file; + { local $/; $file = <$in>; } + close $in; + open my $out, ">:encoding(UTF-8)", $outpath.".html"; + print $out $file; + close $out; + } +); + +sub enter { + my $path = shift; + print "\e[1;34m→\e[0;34m $path\e[0m\n"; + mkdir('out'.$path); + my @dirs; + opendir my $dir, "src".$path or die "cannot open $! for reading"; + my @ls = readdir $dir; + foreach (@ls) { + # keep out dotfiles + my $file = $_; + if ((unpack 'a', $file) eq '.') { next; } + + print " \e[35m·\e[1m $file\e[0;35m "; + if (-d 'src'.$path.$file) { # entry is a directory + print 'deferring directory'; + push @dirs, $file; + } else { # entry is a file + my $ext = filext $file; + if (exists($parsers{$ext})) { + my $outname = 'out'.$path.basename($file); + $parsers{$ext}('src'.$path.$file, $outname, basename($file)); + } else { + print "no handler; copying raw → \e[36mout$path$file"; + system('cp "src'.$path.$file.'" "out'.$path.$file.'"') # haaaaack + } + } + print "\e[0m\n"; + } + closedir $dir; + foreach (@dirs) { + my $dir=$path.$_."/"; + enter($dir); + } +} + +if (-d "out") { system("rm -r out/*"); } # haaaaaaack + else { mkdir "out"; } + +enter("/"); + +print "\e[1mok\e[0m\n"; ADDED src/doc/index.md Index: src/doc/index.md ================================================================== --- src/doc/index.md +++ src/doc/index.md @@ -0,0 +1,36 @@ +# tsunami +tsunami is a self-contained static site generator written in perl. it takes a collection of markdown files (among others) and transforms them into simple, lightweight html that can be styled by the user. however, it also includes a default stylesheet. + +tsunami is designed to be modified according to the needs of each site. new translation functions can be defined relatively simply, and the html structure of the generated documents is hardcoded. (this is partly to gently discourage use of this generator to produce sites loaded down with unnecessary javascript.) + +this compiler is named "tsunami" because its code is a disaster. + +## license +unless indicated otherwise in the headers of individual files, the contents of this repository are released under the Affero General Public License v3. + +## dependencies +tsunami's only dependency is a working Perl 5 installation. + +## directory hierarchy +the first thing to understand is how your tsunami project is laid out. its root directory contains three folders (`src`, `cfg`, and `out`) and the scripts `pub.pl` and `up.sh`. + +the `src` directory contains your *input files*. in other words, whenever you want to add something to the site, you'll do it by putting it in here. by default, it also contains the `doc` directory, which holds this documentation. you may want to move it somewhere else before you publish your real site, but leaving it in place won't do any harm. +* *see: [input files](input-files.html)* + +the `cfg` directory contains top-level configuration for the site. currently the only items here are `links` and `sitename`. both of these files can contain *comments*, which are text ignored by the software that builds the site. a line can be marked as a comment by starting it with whitespace (spaces or tabs). blank lines are ignored. + +* `links` is used to change the contents of the navigation bar just under the header. take a look at the file for a more detailed explanation of how to use it. +* `sitename` contains one or two lines, a title and a subtitle for the site. these are printed at the top of every page. + +`out` only exists if you have run `pub.pl` at least once. it contains a generated site ready to upload. **never edit files in `out`!** any changes you make will be overwritten as soon as you regenerate the site. + +## build script +the program that examines the input files and generates a site from them is `pub.pl`. whenever you change the configuration or the contents of `src`, you can run `pub.pl` to update `out` to reflect the changes. +* *see: [using pub.pl](using-pub.html)* + +whenever you run `pub.pl`, it iterates over everything in `src` and builds a matching directory tree in `out`. it populates this tree with the “compiled” form of each file it finds. see [input files](input-files.html) for more information on this process. + +`pub.pl` is the core of the toolchain and is the only thing you need to start a new tsunami project, as long as you remember to put the configuration and input files in the right place. + +## upload script +the file `up.sh` is a script that automates [uploading your site](upload.html) to GitHub Pages. ADDED src/doc/input-files.md Index: src/doc/input-files.md ================================================================== --- src/doc/input-files.md +++ src/doc/input-files.md @@ -0,0 +1,9 @@ +# input files +whenever you want to add a page to your site, you add a corresponding file in `src`. `pub.pl` does different things to each file depending on its *extension*, that is, the string following the last `.` in a file's name. for instance, in the filename `index.md`, the extension is `md`. + +* [markdown](markdown.html) (`md`): markdown is a lightweight, human-readable, human-writable syntax for adding formatting cues to plain-text documents. when `pub.pl` encounters a `.md` file, it formats it in HTML and saves the compiled version as a `.html` file. so for instance, if you have a file `src/index.md`, this will be compiled to `out/index.html`. +* **text files** (`txt`): text files are handled similarly to markdown files except they are not processed for formatting cues. they are given a top-level header based on the filename and each line is split into a paragraph. there is no way to add formatting such as bold text, links, or lists. +* **HTML files** (`html`): if you need more control than markdown can give you, you can place snippets of HTML code directly in the `src` directory tree. these should *not* be full HTML documents as their contents will be embedded in the standard page template. `html` files receieve no processing. +* **any other file types**, including files with no extension, are copied raw to `out`. this includes things like images, stylesheets, audio, and video. + +if for whatever reason you need to include the raw, completely unformatted version of `md`, `txt`, or `html` file (such as to give your site a functional `robots.txt`), you can simply place `.raw` after the true file extension. for example, `src/robots.txt.raw` is copied unchanged to `out/robots.txt`. ADDED src/doc/markdown.md Index: src/doc/markdown.md ================================================================== --- src/doc/markdown.md +++ src/doc/markdown.md @@ -0,0 +1,56 @@ +# markdown +[markdown](https://daringfireball.net/projects/markdown/syntax) is a lightweight markup language ideal for static site generators. this page contains information on how to write markdown files. `pub.pl` uses a slightly modified version. + +## filetype +a markdown file is a *plain-text file* ending with the extension `.md`. you can create a file like this at the command line with a command like `touch file.md` or in a text editor like TextEdit or pluma. note that rich text editors like TextEdit must to explicitly told to switch to plain-text mode; the necessary command may be found in the “Format” menu, the save dialog, or elsewhere. consult your editor’s documentation for more information. + +## syntax +every *logical line* (that is, sequence of characters terminated by an *enter* or *return)* constitutes a separate paragraph. + +headers are added to markdown files with the `#` and `##` cues. any line starting with `#` is a top-level header (like the header above that says “markdown”). a line that starts with `##` is a second-level header + +## formatting +text can be formatted with the `\*` characters. placing a pair of stars around a sequence of text makes the text *italic* (`\*italic\*`). placing a double pair of stars (`\*\*`) around a phrase makes it **bold** (`\*\*bold\*\*`). finally, a *triple* pair of stars (`\*\*\*`) makes it ***bold and italic*** (`\*\*\*bold and italic\*\*\*`). + +you can also use the `\_` character to _underline_ text (`\_underline\_`), although this should be used sparingly. conventionally, underlines on the internet denote links, and while the default stylesheet makes links and underlined text very distinct, they are probably still best avoided. + +code and other literals can be written by surrounding them with the character ```, for instance, `src/index.md` (`\`src/index.md\``). + +## lists +markdown can create two types of lists, ordered lists and unordered lists. + +ordered lists are created by prefixing lines with a number followed by a `.`; e.g., `1. line one`; `2. line two`: + +1. line one +2. line two + +unordered lists are created by placing an asterisk `\*` at the start of the line; e.g. `\* line one`; `\* line two`: + +* line one +* line two + +note that the asterisk *must* be followed by a space to distinguish a list entry from line-initial italics. + +## links +to add a link to another file or website, surround the *linked text* with square brackets and place a URL directly next to it in parentheses. for example, the link [index](/index.html) is written `\[index](/index.html)`. there cannot be a space between the `]` and `(`. + +you can link to other documents in the same site, external sites, sections of the same page, or sections of other pages. sections are denoted with the `#` character, so a link to [convenience replacements](#convenience-replacements) can be written as `\[convenience replacements](#convenience-replacements)`. a link from another page to this section could be written `\[links](markdown.html#links)`. + +[addressing files](path.html) is fairly complex, and has its own section. + +## escapes +there's a small problem here - what if you need to include a literal `\*` or `\_` in a file, such as in an equation (12\*2) or a function signature (`void do\_things\_with\_stuff(struct stuff\* s)`)? in this case, we use the standard *escape character*, the backslash `\ `. + +by placing a backslash in front of a formatting character (including another backslash), the character loses its special meaning, and becomes just another symbol (as in `void do\\\_things\\\_with\\\_stuff(struct stuff\\* s)`) above. + +## horizontal rule +to separate two paragraphs with a line, you can use the sequence `-\-\-` to generate a *horizontal rule:* +--- +this is often used to indicate perspective breaks in stories or to separate unnamed sections in essays. note that the `-\-\-` sequence must occur on *its own line* with no other content, including spaces. + +## convenience replacements +the sequence `-\-` is automatically transformed into an *em-dash* (--). this may be prevented by writing it as `-\\-`. + +the character `x` is printed as a multiplication sign (×) when it occurs directly between two digits, as in 12x4 (`12\x4`); this may be prevented by prefacing the `x` with a backslash, as in `12\\x4`. + +the sequence `-\:-` is printed as a division sign (-:-), as in 100-:-10 (`100-\:-10`); this may be prevented by prefacing the `:` with a backslash, as in `100-\\:-10`. ADDED src/doc/path.md Index: src/doc/path.md ================================================================== --- src/doc/path.md +++ src/doc/path.md @@ -0,0 +1,27 @@ +# file paths +a key concept in web design is the *file path*. a file path is simply a string that describes the location of a file in a filesystem. each directory (or "folder") that you have to open before you can reach the file is separated from the filename by a forward slash. so if you have a file `data` saved in the folder `b`, which itself is in the folder `a`, you would refer to it by the path `a/b/data`. + +when you reference one file from another (such as by [linking](markdown.html#links) to it), it's important to note that the URL must be that of the *compiled address* of a file. while the file you are currently reading is named `markdown.md` behind the scenes, `pub.pl` generates an HTML file from it, with the name `markdown.html`. for more information on how filenames (and files) are transformed, see [input files](input-files.html). + +you can create both relative and absolute links. relative links are from the perspective of the directory that the current file is located it. so if you're editing a file in the same directory as the file you're linking to, you can simply write the name of the file. however, if it's in another directory, you might want to use an *absolute path:* any URL that begins with a `/` points to something in the root `src` directory. so the file `index.md` in the `docs` directory could be reached from here by the URL `index.html` *or* the URL `/docs/index.html` (`/index.html` being a different file entirely). + +if you need to link to something that's one directory up but don't want to use an absolute URL, you can instead use the `../` notation. `..` is a special directory link that points back up to parent of the current directory. since this file is located in the `/docs` directory, we could link from it to `index.md` as either `/index.html` or `../index.html`. in general, you should only do this if both this file and the other one are in a directory whose path is liable to be changed. as an example, all links between documentation files are relative, so the `doc` folder can be moved or renamed without breaking them. + +to link to a page on a completely different site, just copy the whole URL from your address bar (including the `http://` or `https://` part) and put it between the parentheses. for instance, this link to [google](https://google.com) is written `\[google](https://google.com)`. + +to give you a better sense of path syntax, here's a list of every file and directory in the default distribution with its full path. you can open up a file browser to see how this works, or open a [terminal](using-pub.html), `cd` to the project directory and run the `tree` command to see a visual print-out of the whole directory structure. + +* `/pub.pl` +* `/up.sh` +* `/cfg` +* `/cfg/links` +* `/cfg/sitename` +* `/src` +* `/src/index.md` +* `/src/style.css` +* `/src/header.png` +* `/src/doc` +* `/src/doc/index.md` +* `/src/doc/input-files.md` +* `/src/doc/markdown.md` +* `/src/doc/using-pub.md` ADDED src/doc/upload.md Index: src/doc/upload.md ================================================================== --- src/doc/upload.md +++ src/doc/upload.md @@ -0,0 +1,6 @@ +# uploading +the tsunami tree comes with a script to upload its output to a GitHub Pages site. to do this, open a [terminal](using-pub.html), `cd` to the root of the tsunami project, and run the command `./up.sh`. + +the script uses an *OAuth token* to communicate with the GitHub server so you don't need to enter your password when you update the site. you need to get one from your github account settings and supply it to `up.sh` on first run. + +if you don't need to check the local output before you update the site, you can use the command `./pub.pl; ./up.sh` to accomplish in one go. ADDED src/doc/using-pub.md Index: src/doc/using-pub.md ================================================================== --- src/doc/using-pub.md +++ src/doc/using-pub.md @@ -0,0 +1,35 @@ +# using pub.pl +the `pub.pl` tool is what is called a *command line application*, a *terminal program*, or a *shell program*. this means that it has no graphical interface, and operates simply by reading and writing text to and from files and the keyboard. + +to interface with command line tools, we need to use a *terminal emulator*. on Mac OS X this is the Terminal app in the Utilities folder (`/Applications/Utilities/Terminal.app`). on newer versions of the OS, the Utilities folder is sometimes hidden; you can reach it by switching to the Finder, holding down **Command** and **Shift**, and pressing the `U` key. on Linux, this is a tool such as `gnome-terminal`, `mate-terminal`, or `urxvt`. + +once you've opened the terminal, there are a few core concepts you need to understand. + +## the shell +the *shell* is the command-line application that starts running as soon as you load the terminal. it displays a prompt (by default, usually a string ending in `$`) and accepts *commands.* the shell handles basic file management tasks and launching other applications. + +you enter a command into a shell by typing it into the window and pressing the **Return** or **Enter** key. the command performs a task like moving a file or launching a program. when the command finishes, another prompt will be displayed. many commands do not print anything while they are running, so you will simply see a cursor sitting on a blank line until they terminate. + +## running `pub.pl` +the only commands you need to understand in order to run `pub.pl` is the `cd` command. the shell can be thought of a bit like a Finder window. a Finder window displays a view of a single folder and lets you take actions on the contents. in the shell's case, this folder is known as the *working directory.* + +the `cd` command changes the working directory. it's the analogue of double-clicking on a folder. in order to run `pub.pl`, we need to change the working directory to the one that `pub,pl` is located in. the precise command needed varies depending on where you've put the folder containing your website. if it's in your home folder, you can reach it with the command `cd ~/evergreen`; if it's on your desktop, you can reach it with `cd ~/Desktop/evergreen`. if you've changed the name from `evergreen`, you should write that new name instead. + +(a useful trick is *shell autocomplete* -- once you typed part of a name, you can press the **Tab** key and the shell will try to figure out what file or folder you meant.) + +once you've reached the right directory, you can run `pub.pl` and generate your site. you do this by entering `./pub.pl` at the prompt and pressing **Enter**. if you receive an error, try running `chmod +x pub.pl` and then trying again. + +as `pub.pl` runs, it will display its current status, printing a list of the files it is operating on. once it has finished, it will display the text `ok` and then return you to your shell. + +it might be useful to keep a shell open while you work on your website so you can quickly regenerate it. if you do this, it might be useful to know that you can re-run the last command simply by pressing the up arrow and then pressing **Enter** as usual. + +## output +the compiled forms of the input files are stored in the `out` folder. you can double-click on them to open them in a browser. to upload them to your web host, see [uploading](upload.html). + +## technical details + +`pub.pl` is not a binary. as the name suggests, it is self-contained script written in the Perl programming language with no external dependencies besides the Perl interpreter. it should be broadly portable to any POSIX-compliant operating system, and it's possible it runs on Windows, at least under Cygwin. i don't know, haven't tried, and don't care. + +`pub.pl` ignores all files and folders whose names begin with `.`, keeping out profligate nonsense like the `.DS_Store` files OSX so enjoys spamming all over every filesystem it gets its greasy hands on, and allowing you to place metadata of your own choosing inside the source tree. + +the source code of `pub.pl` is poorly commented and thorny as hell; it in general should be edited only with extreme care and looked upon only as a source of horrified amusement. ADDED src/index.md Index: src/index.md ================================================================== --- src/index.md +++ src/index.md @@ -0,0 +1,2 @@ +# tsunami +this site has been automatically generated from a collection of source files. read the [documentation](/doc/index.html) on how to use the toolchain and start publishing your own site. ADDED src/style.css Index: src/style.css ================================================================== --- src/style.css +++ src/style.css @@ -0,0 +1,138 @@ +@import url('https://fonts.googleapis.com/css?family=Alegreya+Sans:100,400,700|Alegreya:400,700|Eczar:400,700'); + +body { + background: #1D2520; + color: #dedede; + font-family: "Alegreya Sans", sans; + font-size: 14pt; + margin-top: 0; + margin: 0; + padding: 0; +} +.inset { + margin: 1em; +} +a[href] { + color: #65DE85; + font-weight: bold; + text-decoration: none; + text-shadow: 0 1px #233F2A; +} +a[href]:hover { + color: #9EECB2; + text-decoration: underline; +} +nav, article { + max-width: 40em; + margin: auto; + margin-bottom: 1em; +} +header { + padding: .5em 0; + text-align: center; + font-family: Eczar; + text-shadow: 0 0 30px #7EA388; + margin-bottom: 1em; + background: #1d2520; + /* linear-gradient(rgba(29,37,32,.4), #1D2520 105%), + url(header.png); */ + background-size: cover; +} +header h1 { + font-size: 30pt; + color: white; + margin: .3em; + font-weight: normal; +} + +header h2 { + font-size: 20pt; + margin: .3em; + font-weight: normal; +} + +nav a[href] { + display: block; + padding: .5em; + margin-bottom: .5em; + background-color: #2F3E34; + color: #ABFFC1; + font-weight: normal; + font-family: "Alegreya Sans", sans; + font-size: 15pt; + text-align: left; + opacity: 0.7; + border-bottom: 1px solid #191C1A; + text-shadow: 0 1px #191C1A; +} +nav a[href]:hover { opacity: 1; } +nav a[href]:active { background-color: #28302B; color: #425B4C; } +@media (min-width: 450px) { + nav { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: space-between; + } + nav a[href] { + padding: 0.5em 1.5em; + margin-right: 1em; + margin-bottom: 0; + flex-grow: 1; + text-align: center; + } + nav a[href]:last-child { margin-right: 0; } +} + +article { + display: block; + background-color: #364B3C; + padding-bottom: .5em; + text-align: justify; + margin-top: 1px; +} +article > * { padding: 0em 1em; } +article p { margin-top: .7em; margin-bottom: 0; } +article h1, article h2 { + font-family: Eczar; + font-weight: 100; +} +article h1 { + margin-top: 0; + font-size: 24pt; + border-bottom: 1px solid #1D2520; + color: white; + padding-left: .5em; + padding-top: .2em; + margin-bottom: 0; + text-shadow: 0 1px #191C1A; +} +article h2 { + font-size: 18pt; + border-top: 1px solid #1D2520; + padding-top: 0.1em; + margin-top: 1.5em; + padding-left: .5em; + margin-bottom: -0.5em; /* grrrrr */ + color: #f0f0f0; +} +hr { + height: 0; + border: none; + margin: .5em 2em; + border-bottom: 1px solid #7B9B84; + padding-bottom: 1px; +} +ol, ul { + margin-left: 2em; +} +li { + padding-bottom: .3em; +} +code { + font-family: monospace; + background-color: #4E6554; + padding: .05em .2em; + text-shadow: 0 1px #191C1A; + border-bottom: 1px solid #29382E; +} ADDED up.sh Index: up.sh ================================================================== --- up.sh +++ up.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env bash +# [ʞ] up.sh +# ~ lexi hale