tsunami  Check-in [6f8377c8fe]

Overview
Comment:initial commit
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 6f8377c8fe27e68bddae90118bcdc6f211ee0442e4875d64437675cb12a6b9d6
User & Date: lexi on 2019-06-09 00:17:29
Other Links: manifest | tags
Context
2019-06-09
00:25
fix fmt Leaf check-in: dae97ddb58 user: lexi tags: trunk
00:17
initial commit check-in: 6f8377c8fe user: lexi tags: trunk
00:02
initial empty check-in check-in: 441f4d78a1 user: lexi tags: trunk
Changes

Added cfg/links version [258d2974fb].

            1  + this  is just  a space-delimited  list of  main links.  the
            2  + first part should  contain the URL to link  to, relative to
            3  + the root of the generated site.
            4  +
            5  + for instance, if you have a file in src/stories/a-story.md,
            6  + you would write /src/stories/a-story.html.
            7  +
            8  + note that URLs cannot contain spaces! also, lines beginning
            9  + with a space are treated as comments and are ignored by the
           10  + parser.
           11  +
           12  +/index.html	home
           13  +/about.html	about
           14  +/doc/index.html tsunami docs

Added cfg/sitename version [f4f70cda40].

            1  + this is the text that is displayed in your header.
            2  + the first line is wrapped in <h1>, the second in <h2>
            3  + any further lines are ignored. blank lines and lines
            4  + beginning with whitespace are ignored.
            5  +
            6  +tsunami
            7  +a simple website generator

Added pub.pl version [aa8b31b797].

            1  +#!/usr/bin/perl
            2  +use warnings;
            3  +use feature "unicode_strings";
            4  +use utf8;
            5  +binmode STDOUT, ':utf8';
            6  +
            7  +sub err { print "\e[1;31merror:\e[0m ".$_[0]."\n"; exit 1; }
            8  +if (! -e "pub.pl") {
            9  +	err "\e[1mpub.pl\e[0m must be run from the directory it lives in";
           10  +}
           11  +
           12  +sub filext {
           13  +	my $name = shift;
           14  +	my $ext = $name;
           15  +	$ext =~ s/^([^.]*\.)*//;
           16  +	if ($ext eq $name) {
           17  +		return "";
           18  +	} else {
           19  +		return $ext;
           20  +	}
           21  +}
           22  +sub basename {
           23  +	my $name = shift;
           24  +	$name =~ s/\.[^.]*$//;
           25  +	return $name;
           26  +}
           27  +
           28  +sub isws { my $c = shift;
           29  +	return (($c eq " ") or ($c eq "\t"));
           30  +}
           31  +
           32  +sub readconf {
           33  +	my $filename = shift;
           34  +	open my $fd, "<:encoding(UTF-8)", "cfg/".$filename
           35  +		or err "could not open $filename ($!)\nmake sure it exists";
           36  +	my @lines;
           37  +	while (my $ln = <$fd>) {
           38  +		chomp $ln;
           39  +		if(isws(substr($ln,0,1))) {next;} # line is comment
           40  +		if($ln eq "") {next;} # line is blank
           41  +		push @lines, $ln;
           42  +	}
           43  +	close $fd;
           44  +	return @lines;
           45  +}
           46  +
           47  +sub confpairs {
           48  +	sub sep {
           49  +		my $str = shift; my @seps = @_; my $low = -1;
           50  +		foreach (@seps) {
           51  +			my $pos = index($str, $_); if ($pos != -1) {
           52  +				if (($low == -1) or ($pos < $low)) { $low = $pos; }
           53  +			}
           54  +		}
           55  +		return $low;
           56  +	}
           57  +	my @lines = @_;
           58  +	my @pairs;
           59  +	foreach (@lines) {
           60  +		my $ln = $_;
           61  +		my $i = sep $ln, ' ', "\t";
           62  +		my $j = $i;
           63  +		while ($j < length $ln) { if(isws(substr $ln, $j, 1)) { ++$j; } else {last;}}
           64  +		my $key = substr $ln, 0, $i;
           65  +		my $value = substr($ln, $j, length($ln));
           66  +		push @pairs, [$key, $value];
           67  +	}
           68  +	return @pairs;
           69  +}
           70  +
           71  +my @header = readconf("sitename");
           72  +my @links = readconf("links");
           73  +my @linkpairs = confpairs(@links);
           74  +
           75  +sub depth {
           76  +	my $path = shift;
           77  +	my $ct = () = $path =~ /\//g;
           78  +	return $ct;
           79  +}
           80  +
           81  +sub root {
           82  +	my $depth = shift;
           83  +	-- $depth;
           84  +	if ($depth == 0) {
           85  +		return ".";
           86  +	} elsif ($depth == 1) {
           87  +		return ".."
           88  +	} else {
           89  +		my $str = "..";
           90  +		for (my $i = 0; $i!=$depth; ++$i) {
           91  +			$str .= "/..";
           92  +		}
           93  +		return $str;
           94  +	}
           95  +}
           96  +
           97  +sub page {
           98  +	my ($path, $body) = @_;
           99  +	my $root = root depth $path;
          100  +	my $title;
          101  +	if ($#header >= 0) {
          102  +		$masthead = "\n\t\t<h1>$header[0]</h1>\n\t";
          103  +		$title = $header[0];
          104  +		if ($#header > 0) {
          105  +			$masthead .= "\t<h2>$header[1]</h2>\n\t";
          106  +		}
          107  +	} else {
          108  +		err "no site name specified";
          109  +	}
          110  +	my $nav = "";
          111  +	foreach (@linkpairs) {
          112  +		my $dest = $root . $_->[0];
          113  +		my $lbl = $_->[1];
          114  +		$nav .= qq[<a href="$dest">$lbl</a>\n\t\t\t];
          115  +	}
          116  +	return qq[<!doctype html>
          117  +<html>
          118  +<head>
          119  +	<meta charset="utf-8">
          120  +	<title>$title</title>
          121  +	<link rel="stylesheet" href="$root/style.css">
          122  +</head>
          123  +<body>
          124  +	<header>$masthead</header>
          125  +	<div class="inset">
          126  +		<nav>
          127  +			$nav
          128  +		</nav>
          129  +		<article>
          130  +			$body
          131  +		</article>
          132  +	</div>
          133  +</body>
          134  +</html>]
          135  +}
          136  +
          137  +sub filter {
          138  +	$_[0] =~ s/&/&amp;/g;
          139  +	$_[0] =~ s/</&lt;/g;
          140  +	$_[0] =~ s/>/&gt;/g;
          141  +}
          142  +use constant {
          143  +	PLAIN => 1,
          144  +	ORDLIST => 2,
          145  +	STARLIST => 3
          146  +};
          147  +my %parsers = (
          148  +	'md' => sub { my ($inpath, $outpath) = @_;
          149  +		print "parsing markdown → \e[36m$outpath.html\e[0m";
          150  +		my $root = root depth $outpath;
          151  +		open my $in, "<:encoding(UTF-8)", $inpath;
          152  +		open my $out, ">:encoding(UTF-8)", $outpath.".html";
          153  +		my $pg = "";
          154  +		my $ctx = PLAIN;
          155  +		while (my $ln = <$in>) {
          156  +			chomp $ln;
          157  +			if ($ln ne "") {
          158  +				filter $ln;
          159  +				my $lntype;
          160  +				if ($ln =~ m{^\s*[0-9]*\.}) {
          161  +					$lntype = ORDLIST;
          162  +					$ln =~ s;^\s*[0-9]*\.\s*;;;
          163  +				} elsif ($ln =~ m{^\s*\*\s+}) {
          164  +					$lntype = STARLIST;
          165  +					$ln =~ s-^\s*\*\s+--;
          166  +				} else {
          167  +					$lntype = PLAIN;
          168  +				}
          169  +
          170  +				if ($ln eq "---") { $pg .= "<hr>\n"; next; }
          171  +
          172  +				# im sorry ok
          173  +				$ln =~ s;(?<!\\)\[(.+?)\]\(/(.+?)\);<a href="$root/$2">$1</a>;g;
          174  +				$ln =~ s;(?<!\\)\[(.+?)\]\((.+?)\);<a href="$2">$1</a>;g;
          175  +				$ln =~ s;(?<!\\)\*\*(.+?)(?<!\\)\*\*;<strong>$1</strong>;g;
          176  +				$ln =~ s;(?<!\\)\*(.+?)(?<!\\)\*;<em>$1</em>;g;
          177  +				$ln =~ s;(?<!\\)_(.+?)(?<!\\)_;<u>$1</u>;g;
          178  +				$ln =~ s;(?<!\\)`(.+?)(?<!\\)`;<code>$1</code>;g;
          179  +				$ln =~ s;--;—;g;
          180  +				$ln =~ s;-\\-;--;g;
          181  +				$ln =~ s;-:-;÷;g;
          182  +				$ln =~ s;-\\:-;-:-;g;
          183  +				$ln =~ s;\\(.);$1;g;
          184  +				$ln =~ s;([0-9])x([0-9]);$1×$2;g;
          185  +				$ln =~ s;([0-9])\\x([0-9]);$1x$2;g;
          186  +
          187  +				if ($lntype != $ctx) { #context change
          188  +					if ($ctx == ORDLIST) {
          189  +						$pg .= "</ol>\n";
          190  +					} elsif ($ctx == STARLIST) {
          191  +						$pg .= "</ul>\n";
          192  +					}
          193  +					$ctx = $lntype;
          194  +					if ($ctx == ORDLIST) {
          195  +						$pg .= "<ol>\n";
          196  +					} elsif ($ctx == STARLIST) {
          197  +						$pg .= "<ul>\n";
          198  +					}
          199  +				}
          200  +				if ($ctx == PLAIN) {
          201  +					if ($ln =~ s;^(#+)\s*;;) {
          202  +						my $hl = length($1);
          203  +						my $id = $ln;
          204  +						$id =~ s;[^a-z0-9_\-];\-;g;
          205  +						$pg .= qq[<h$hl id="$id">$ln</h$hl>\n];
          206  +					} else {
          207  +						$pg .= "<p>$ln</p>\n";
          208  +					}
          209  +				} elsif (($ctx == ORDLIST) or
          210  +						($ctx == STARLIST)) {
          211  +					$pg .= "<li>$ln</li>\n";
          212  +				}
          213  +			}
          214  +		}
          215  +		print $out page $outpath.".html", $pg;
          216  +		close $in;
          217  +		close $out;
          218  +	},
          219  +	'txt' => sub { my ($inpath, $outpath, $basename) = @_;
          220  +		print "filtering text → \e[36m$outpath.html\e[0m";
          221  +		open my $in, "<:encoding(UTF-8)", $inpath;
          222  +		open my $out, ">:encoding(UTF-8)", $outpath.".html";
          223  +		my $pg = "<h1>$basename</h1>\n";
          224  +		while (my $ln = <$in>) {
          225  +			chomp $ln;
          226  +			if ($ln ne "") {
          227  +				filter $ln;
          228  +				$pg .= "<p>$ln</p>\n";
          229  +			}
          230  +		}
          231  +		print $out page $outpath.".html", $pg;
          232  +		close $in;
          233  +		close $out;
          234  +	},
          235  +	'html' => sub { my ($inpath, $outpath) = @_;
          236  +		print "wrapping html → \e[36m$outpath.html\e[0m";
          237  +		open my $in, "<:encoding(UTF-8)", $inpath;
          238  +		my $file;
          239  +		{ local $/; $file = <$in>; }
          240  +		close $in;
          241  +		open my $out, ">:encoding(UTF-8)", $outpath.".html";
          242  +		print $out page $outpath.".html", $file;
          243  +		close $out;
          244  +	},
          245  +	'raw' => sub { my ($inpath, $outpath) = @_;
          246  +		print "copying raw → \e[36m$outpath\e[0m";
          247  +		open my $in, "<:encoding(UTF-8)", $inpath;
          248  +		my $file;
          249  +		{ local $/; $file = <$in>; }
          250  +		close $in;
          251  +		open my $out, ">:encoding(UTF-8)", $outpath.".html";
          252  +		print $out $file;
          253  +		close $out;
          254  +	}
          255  +);
          256  +
          257  +sub enter {
          258  +	my $path = shift;
          259  +	print "\e[1;34m→\e[0;34m $path\e[0m\n";
          260  +	mkdir('out'.$path);
          261  +	my @dirs;
          262  +	opendir my $dir, "src".$path or die "cannot open $! for reading";
          263  +	my @ls = readdir $dir;
          264  +	foreach (@ls) {
          265  +		# keep out dotfiles
          266  +		my $file = $_;
          267  +		if ((unpack 'a', $file) eq '.') { next; }
          268  +		
          269  +		print " \e[35m·\e[1m $file\e[0;35m ";
          270  +		if (-d 'src'.$path.$file) { # entry is a directory
          271  +			print 'deferring directory';
          272  +			push @dirs, $file;
          273  +		} else { # entry is a file
          274  +			my $ext = filext $file;
          275  +			if (exists($parsers{$ext})) {
          276  +				my $outname = 'out'.$path.basename($file);
          277  +				$parsers{$ext}('src'.$path.$file, $outname, basename($file));
          278  +			} else {
          279  +				print "no handler; copying raw → \e[36mout$path$file";
          280  +				system('cp "src'.$path.$file.'" "out'.$path.$file.'"') # haaaaack
          281  +			}
          282  +		}
          283  +		print "\e[0m\n";
          284  +	}
          285  +	closedir $dir;
          286  +	foreach (@dirs) {
          287  +		my $dir=$path.$_."/";
          288  +		enter($dir);
          289  +	}
          290  +}
          291  +
          292  +if (-d "out") { system("rm -r out/*"); } # haaaaaaack
          293  +	else { mkdir "out"; }
          294  +	
          295  +enter("/");
          296  +	
          297  +print "\e[1mok\e[0m\n";

Added src/doc/index.md version [10143aaa34].

            1  +# tsunami
            2  +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.
            3  +
            4  +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.)
            5  +
            6  +this compiler is named "tsunami" because its code is a disaster.
            7  +
            8  +## license
            9  +unless indicated otherwise in the headers of individual files, the contents of this repository are released under the Affero General Public License v3.
           10  +
           11  +## dependencies
           12  +tsunami's only dependency is a working Perl 5 installation.
           13  +
           14  +## directory hierarchy
           15  +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`.
           16  +
           17  +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.
           18  +* *see: [input files](input-files.html)*
           19  +
           20  +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.
           21  +
           22  +* `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.
           23  +* `sitename` contains one or two lines, a title and a subtitle for the site. these are printed at the top of every page.
           24  +
           25  +`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.
           26  +
           27  +## build script
           28  +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.
           29  +* *see: [using pub.pl](using-pub.html)*
           30  +
           31  +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.
           32  +
           33  +`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.
           34  +
           35  +## upload script
           36  +the file `up.sh` is a script that automates [uploading your site](upload.html) to GitHub Pages.

Added src/doc/input-files.md version [2ff644eab2].

            1  +# input files
            2  +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`. 
            3  +
            4  +* [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`.
            5  +* **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.
            6  +* **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.
            7  +* **any other file types**, including files with no extension, are copied raw to `out`. this includes things like images, stylesheets, audio, and video.
            8  +
            9  +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 version [6813c24283].

            1  +# markdown
            2  +[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.
            3  +
            4  +## filetype
            5  +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.
            6  +
            7  +## syntax
            8  +every *logical line* (that is, sequence of characters terminated by an *enter* or *return)* constitutes a separate paragraph.
            9  +
           10  +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
           11  +
           12  +## formatting
           13  +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\*\*\*`).
           14  +
           15  +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.
           16  +
           17  +code and other literals can be written by surrounding them with the character ```, for instance, `src/index.md` (`\`src/index.md\``).
           18  +
           19  +## lists
           20  +markdown can create two types of lists, ordered lists and unordered lists.
           21  +
           22  +ordered lists are created by prefixing lines with a number followed by a `.`; e.g., `1. line one`; `2. line two`:
           23  +
           24  +1. line one
           25  +2. line two
           26  +
           27  +unordered lists are created by placing an asterisk `\*` at the start of the line; e.g. `\* line one`; `\* line two`:
           28  +
           29  +* line one
           30  +* line two
           31  +
           32  +note that the asterisk *must* be followed by a space to distinguish a list entry from line-initial italics.
           33  +
           34  +## links
           35  +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 `(`.
           36  +
           37  +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)`.
           38  +
           39  +[addressing files](path.html) is fairly complex, and has its own section.
           40  +
           41  +## escapes
           42  +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 `\ `.
           43  +
           44  +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. 
           45  +
           46  +## horizontal rule
           47  +to separate two paragraphs with a line, you can use the sequence `-\-\-` to generate a *horizontal rule:*
           48  +---
           49  +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.
           50  +
           51  +## convenience replacements
           52  +the sequence `-\-` is automatically transformed into an *em-dash* (--). this may be prevented by writing it as `-\\-`.
           53  +
           54  +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`.
           55  +
           56  +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 version [2f0610ce72].

            1  +# file paths
            2  +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`.
            3  +
            4  +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).
            5  +
            6  +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).
            7  +
            8  +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.
            9  +
           10  +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)`.
           11  +
           12  +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.
           13  +
           14  +* `/pub.pl`
           15  +* `/up.sh`
           16  +* `/cfg`
           17  +* `/cfg/links`
           18  +* `/cfg/sitename`
           19  +* `/src`
           20  +* `/src/index.md`
           21  +* `/src/style.css`
           22  +* `/src/header.png`
           23  +* `/src/doc`
           24  +* `/src/doc/index.md`
           25  +* `/src/doc/input-files.md`
           26  +* `/src/doc/markdown.md`
           27  +* `/src/doc/using-pub.md`

Added src/doc/upload.md version [d1820aebbb].

            1  +# uploading
            2  +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`.
            3  +
            4  +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.
            5  +
            6  +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 version [6fa0039d45].

            1  +# using pub.pl
            2  +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.
            3  +
            4  +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`.
            5  +
            6  +once you've opened the terminal, there are a few core concepts you need to understand.
            7  +
            8  +## the shell
            9  +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.
           10  +
           11  +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.
           12  +
           13  +## running `pub.pl`
           14  +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.*
           15  +
           16  +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.
           17  +
           18  +(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.)
           19  +
           20  +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.
           21  +
           22  +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.
           23  +
           24  +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.
           25  +
           26  +## output
           27  +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).
           28  +
           29  +## technical details
           30  +
           31  +`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.
           32  +
           33  +`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.
           34  +
           35  +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 version [8b17442d94].

            1  +# tsunami
            2  +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 version [d804b212c5].

            1  +@import url('https://fonts.googleapis.com/css?family=Alegreya+Sans:100,400,700|Alegreya:400,700|Eczar:400,700');
            2  +
            3  +body {
            4  +	background: #1D2520;
            5  +	color: #dedede;
            6  +	font-family: "Alegreya Sans", sans;
            7  +	font-size: 14pt;
            8  +	margin-top: 0;
            9  +	margin: 0;
           10  +	padding: 0;
           11  +}
           12  +.inset {
           13  +	margin: 1em;
           14  +}
           15  +a[href] {
           16  +	color: #65DE85;
           17  +	font-weight: bold;
           18  +	text-decoration: none;
           19  +	text-shadow: 0 1px #233F2A;
           20  +}
           21  +a[href]:hover {
           22  +	color: #9EECB2;
           23  +	text-decoration: underline;
           24  +}
           25  +nav, article {
           26  +	max-width: 40em;
           27  +	margin: auto;
           28  +	margin-bottom: 1em;
           29  +}
           30  +header {
           31  +	padding: .5em 0;
           32  +	text-align: center;
           33  +	font-family: Eczar;
           34  +	text-shadow: 0 0 30px #7EA388;
           35  +	margin-bottom: 1em;
           36  +	background: #1d2520;
           37  +		/* linear-gradient(rgba(29,37,32,.4), #1D2520 105%),
           38  +		url(header.png); */
           39  +	background-size: cover;
           40  +}
           41  +header h1 {
           42  +	font-size: 30pt;
           43  +	color: white;
           44  +	margin: .3em;
           45  +	font-weight: normal;
           46  +}
           47  +
           48  +header h2 {
           49  +	font-size: 20pt;
           50  +	margin: .3em;
           51  +	font-weight: normal;
           52  +}
           53  +
           54  +nav a[href] {
           55  +	display: block;
           56  +	padding: .5em;
           57  +	margin-bottom: .5em;
           58  +	background-color: #2F3E34;
           59  +	color: #ABFFC1;
           60  +	font-weight: normal;
           61  +	font-family: "Alegreya Sans", sans;
           62  +	font-size: 15pt;
           63  +	text-align: left;
           64  +	opacity: 0.7;
           65  +	border-bottom: 1px solid #191C1A;
           66  +	text-shadow: 0 1px #191C1A;
           67  +}
           68  +nav a[href]:hover { opacity: 1; }
           69  +nav a[href]:active { background-color: #28302B; color: #425B4C; }
           70  +@media (min-width: 450px) {
           71  +	nav {
           72  +		display: flex;
           73  +		flex-direction: row;
           74  +		flex-wrap: wrap;
           75  +		justify-content: space-between;
           76  +	}
           77  +	nav a[href] {
           78  +		padding: 0.5em 1.5em;
           79  +		margin-right: 1em;
           80  +		margin-bottom: 0;
           81  +		flex-grow: 1;
           82  +		text-align: center;
           83  +	}
           84  +	nav a[href]:last-child { margin-right: 0; }
           85  +}
           86  +
           87  +article {
           88  +	display: block;
           89  +	background-color: #364B3C;
           90  +	padding-bottom: .5em;
           91  +	text-align: justify;
           92  +	margin-top: 1px;
           93  +}
           94  +article > * { padding: 0em 1em; }
           95  +article p { margin-top: .7em; margin-bottom: 0; }
           96  +article h1, article h2 {
           97  +	font-family: Eczar;
           98  +	font-weight: 100;
           99  +}
          100  +article h1 {
          101  +	margin-top: 0;
          102  +	font-size: 24pt;
          103  +	border-bottom: 1px solid #1D2520;
          104  +	color: white;
          105  +	padding-left: .5em;
          106  +	padding-top: .2em;
          107  +	margin-bottom: 0;
          108  +	text-shadow: 0 1px #191C1A;
          109  +}
          110  +article h2 {
          111  +	font-size: 18pt;
          112  +	border-top: 1px solid #1D2520;
          113  +	padding-top: 0.1em;
          114  +	margin-top: 1.5em;
          115  +	padding-left: .5em;
          116  +	margin-bottom: -0.5em; /* grrrrr */
          117  +	color: #f0f0f0; 
          118  +}
          119  +hr {
          120  +	height: 0;
          121  +	border: none;
          122  +	margin: .5em 2em;
          123  +	border-bottom: 1px solid #7B9B84;
          124  +	padding-bottom: 1px;
          125  +}
          126  +ol, ul {
          127  +	margin-left: 2em;
          128  +}
          129  +li {
          130  +	padding-bottom: .3em;
          131  +}
          132  +code {
          133  +	font-family: monospace;
          134  +	background-color: #4E6554;
          135  +	padding: .05em .2em;
          136  +	text-shadow: 0 1px #191C1A;
          137  +	border-bottom: 1px solid #29382E;
          138  +}

Added up.sh version [a95f91635f].

            1  +#!/usr/bin/env bash
            2  +# [ʞ] up.sh
            3  +#  ~ lexi hale <lexi@hale.su>
            4  +#  © CC0
            5  +#  > ./up.sh [-q: don't display explanatory messages]
            6  +
            7  +# this  is  a  simple  script to  automate  publishing  a
            8  +# website generated by `tsunami`  to github pages. on its
            9  +# first  run  it will  ask  you  for some  authentication
           10  +# details,  initialize a  git repository,  and store  the
           11  +# parameters  you supply  there. on  subsequent runs,  it
           12  +# will push all changes to the repository.
           13  +
           14  +quiet=$1
           15  +
           16  +msg() { echo " [1;3$1m*" "$2" ''; }
           17  +die() { ((0 == $1)) || { msg 1 "$3"; exit $2; } }
           18  +log() { while read ln; do echo " | $ln"; done }
           19  +say() { test "$quiet" = "-q" || echo $@; }
           20  +ask() {
           21  +	test "$2" == "" &&
           22  +		prompt="$1:" ||
           23  +		prompt="$1 [$2]:" 
           24  +
           25  +	read -p " - $prompt " $1 || {
           26  +		echo
           27  +		msg 1 'user cancelled setup; bailing';
           28  +		exit 1
           29  +	}
           30  +
           31  +	test "${!1}" = "" && {
           32  +		test "$2" == "" && {
           33  +			msg 1 'invalid value supplied; bailing'
           34  +			exit 2
           35  +		} || {
           36  +			read $1 <<< $2
           37  +		}
           38  +	}
           39  +}
           40  +
           41  +cd out >/dev/null 2>&1; die $? 9 "directory 'out' does not exist"
           42  +test ! -e .git && {
           43  +	# first run, set up a repo
           44  +	say 'to use the tsunami upload script, you need to specify a'
           45  +	say 'few parameters. firstly, what is your github username?'
           46  +	ask username
           47  +	say 'you also need to specify an email to associate with your'
           48  +	say 'commits. this WILL be public. you should either use the'
           49  +	say 'same email that is associated with your github account,'
           50  +	say 'or a “cloak” email that github has generated for you.'
           51  +	ask email
           52  +	say 'up.sh uses oauth to communicate with github. generate an'
           53  +	say 'access token and paste it in now.'
           54  +	ask token
           55  +	say 'what repository do you wish to store your site in? hit'
           56  +	say 'enter if you want to use your account repo'
           57  +	ask repo $username.github.io
           58  +	test -e ../src/CNAME || {
           59  +		say 'you don’t have a CNAME file in your src/ directory. if'
           60  +		say 'you want to use your own domain to host this website,'
           61  +		say 'key it in now; otherwise, just hit enter.'
           62  +		ask domain .
           63  +		test "$domain" == "." || {
           64  +			echo "$domain" > ../src/CNAME
           65  +			echo "$domain" > CNAME
           66  +		}
           67  +	}
           68  +
           69  +	msg 6 "initializing $repo.git"
           70  +
           71  +	git init 2>&1 | log
           72  +		die ${PIPESTATUS[0]} 6 "could not initialize repo in out/"
           73  +	git config --local user.name $username 2>&1 | log
           74  +	git config --local user.email $email 2>&1 | log
           75  +	git remote add origin "https://$token:x-oauth-basic@github.com/$username/$repo.git" 2>&1 | log
           76  +		die ${PIPESTATUS[0]} 7 "could not add remote"
           77  +
           78  +	test "$repo" = "$username.github.io" || {
           79  +		msg 6 "renaming branch “master” → “gh-pages”"
           80  +		git branch -m master gh-pages 2>&1 | log
           81  +		die ${PIPESTATUS[0]} 8 "could not rename branch"
           82  +	}
           83  +	msg 6 'making initial commit'
           84  +} || {
           85  +	msg 6 'making new commit'
           86  +}
           87  +
           88  +git add . 2>&1 | log
           89  +	die ${PIPESTATUS[0]} 3 "failed to add files"
           90  +git commit -a -m "update site" 2>&1 | log
           91  +	die ${PIPESTATUS[0]} 4 "failed to commit"
           92  +git push -u origin master --force 2>&1 | log
           93  +	die ${PIPESTATUS[0]} 5 "failed to push"