I got tired of writing gopher map files by hand, so I made up a new format to
be more human friendly. For now I'm calling it snarkp since that's the first
name that came to mind.

Info lines in gopher have to start with the character 'i' and have to have a
fake resource, host, and port (some clients don't mind some of those being
missing, but others explode on malformed lines.) In the current time, a lot of
gopher menus have a lot of info lines for text and ASCII art, so it gets tiring
doing this.

In snarkp files, any line of text is an info line and no extra path, host, or
port are added. Lines that do point to resources are prefixed with a backslash,
followed by the item type, description string, resource path, host, and port.
For example, a line pointing to a text file would look like this:

\0      The baz text file       /baz.txt        foobar.net      70

It also gets tedious writing the same hostname and port over and over again for
every single menu line you need to write, so snarkp lets you omit those. A
native snarkp client would remember the host and port it retrieved the current
menu from, and reuse them for lines with no port or host specified. So if you
download this line from foobar.net on port 88:

\0      Some stuff.     /stuff.txt

then the client would know to request "/stuff.txt" from the same place,
foobar.org on port 80.

Since no such client exists, I wrote a snarkp to gopher converter that takes a
hostname and port as options to fill in. When it sees a missing host or port in
the snarkp, it outputs the designated hostname or port for that field.

Another problem with having to specify host and port in gophermaps is that if
you decide to move to a different server, every file you've written is invalid
now. Snarkp files can avoid that problem. The same problem applies to the
resource path. For example, on sdf.org all my files are under "/users/lumia/"
but if I were to host my own gopher server, they'd all likely be under "/"
instead. I'd have to change every single resource path in my gophermaps.

To solve this, snarkp supports relative paths. This adds more complexity to the
client, but not too much. If a resource name starts with a "/", then it's
considered an absolute path and isn't changed. Otherwise, it's considered
relative to the base path of the current menu. The base path can be derived
from the path of the current menu with these rules:

1. If the path ends in a "/" then it is the base path.

       ex: The base path of resource "/foo/" is "/foo/"

2. If the path ends in ".snp" then everything after the last "/" is not part of
  the base path. If the path contains no "/" characters then the base path is
  "/"

  ex: The base path of "/foo/menu.snp" is "/foo/"
  ex: The base path of "menu.snp" is "/"

3. If the path does not end in a "/", then the base path is the path with a "/"
  appended to the end.

  ex: The base path of "foo" is "foo/"

When accessing a relative path, the client just concatenates the base path of
the current menu with the relative path being accessed inside the menu. If a
client downloads a menu via the resource name "/users/lumia/snarkp.snp" and
inside that menu is this item:

\0      An item.        item.txt

Then the full path for that file would be "/users/lumia/item.txt". For snarkp
to gopher conversion, the base path has to be supplied to the conversion tool.