README
“Just write,” they said, “It doesn’t matter what tool you use…”
Writing is the hard part, everything else is just formatting. You could scratch your novel into a wall with a rock, or use a modal command line text editor, the point is: you should be focusing on writing. Your tool should be a secondary concern.
…says the README file trying to sell me on a writing tool…
Right? I’m losing the sale before the customer even drove the car, but Giterary isn’t really selling something (it happens to free, open source software, which brings together other, powerful, freely available tools).
So, what does Giterary do as a writing tool? Giterary is a tool that suggests a better way to work, helps you if it can, concentrating on making the hard things easy, and keeping the simple stuff simple. It can get out of the way if you want to just write, but it’ll make your life less complex down the road.
“A first novel won’t be as much work as you think. It will be much more. ”
Consider the scale of a novel. For the most part, published writing projects weigh in at around ~50,000 to 100,000 words (and often more). They can take years to write, after which they tend to require extensive editing, re-reads, re-writes, and whatever requisite iterations it takes to make a better product.
Now consider a machine with ~50,000 to 100,000 moving parts. A novel-machine that takes a human’s attention as input and outputs compelling plot, worthwhile characters, and subtlety. As the engineer/author, it’s your job to fabricate the machine parts, construct them correctly, and maybe apply a layer of paint. Sure, maybe it works for you the first time you run it, but when you ask your best friend to take a spin it seizes midway past the second-stage turbine spooling. You walk slowly through the smoldering wreckage. Your friend is alright. Your pride is not. And you forgot to take notes the first time around.
The point is: if writing a novel is hard, maintaining a novel is complex. The latter of which is overlooked when just writing is a primary concern.
Giterary offers a set of nice things to write and maintain a novel, managing complexity at both ends of the process, and hopefully without you noticing. How does it do this? Well…
When programmers are lazy, everyone benefits.
Computer programmers look at your machine with 100,000 moving parts and laugh. Software weighs in at tens of thousands to a few million lines of source code. They don’t even bother to count the words, were there even words to count.
They laugh because they solved the management of that complexity a long time ago. Lo, and they chanted in their sing-song way, “A hundred people need to work on something with at least a million lines of code. And they should all be able to work at the same time, and be able to detect and communicate their changes efficiently, and maintain detailed histories of their changes, and gracefully solve conflicts, should they arise.” And thus it was so, and they’ve been improving on this concept ever since.
If your novel were like the programmers’ source code, you’d be able to manage your novel with these all-powerful tools of the programmer gods. The thing is, your novel is source code, much like its words are part of your novel-machine. It’s just a matter of formatting.
That’s nice. So what does this do, again?
Giterary is a wiki application with a cool synchronization tool. It helps you write, and helps you maintain your novel.
Giterary suggests you write your chapters in Markdown syntax (but you don’t absolutely have to). Markdown is a text-based format that lets you do complex formatting by just writing, and largely ignoring things like formatting, markup, and tedium. It also extends Markdown’s functionality by allowing textual annotations and “wikilinking” between your files, similar to Wikipedia, letting you build a web of references to information you need.
Giterary puts these text-based files into a hierarchical directory structure of your choosing, and manages these files using a git repository. The git repository stores all versions of all files, and Giterary wraps around the git repository to let you easily see information about your files, down to showing you when you swapped out “she said” with “she said, languorously.”
The killer feature, though, is git’s ability to act as a distributed database. You can take the entirety of your Giterary instance, clone it to any computer, make changes, and then push them back. Need to work offline on the plane, but submit your changes once you’re back in civilization? Not a problem.
Nobody has time for that noise, I just want to write. Why would I need that?
Three reasons:
You are forgetting all the time. You just forgot something.
I barely remember last week. Yesterday’s already fuzzy around the edges. Things I wrote a year ago might as well have been written by a different person, with different hopes and dreams. And while I can’t talk to that person, using Giterary will let me see what that stranger did, and if they provided notes, see what they were thinking.
Giterary helps you talk to the past, and leave messages for the future.
It may not only ever be you making the changes.
You never thought about that, did you, hot shot? Well, yeah, I guess maybe you did. The possibility of multiple authors isn’t unheard of, but that pales in comparison to the most common case: you will eventually need to turn your things over to an editor.
You can submit a massive, monolithic Word document via email and hope Track Changes does the job. But what do you do while you’re waiting for them to send your document back? What if you’re still working on a chapter? How do you maintain which is the “master” copy, and which is for edits? Do you copy-paste your edits, like the beasts of the wild?
If you feel shame, that’s okay. It means the healing can begin. Giterary provides an intelligent system to manage change, and to do so immediately, letting you maintain a sane workflow for you, your potential co-authors, and your editors.
Backups are nice. Backed up git repositories are nicer.
Giterary isn’t a backup tool, but this is because other things solve this problem much more reliably and elegantly. Getting automated backups should be a concern of anyone who can’t afford to lose files.
However, assume bad things happen: your hard drive craters, your computer is stolen, or you accidentally deletes files. It’s fine, because you backed up your files, right? Right? Right. But then the question becomes: when was your last backup? Did that have the latest version of X, Y, or Z? You can look at the timestamps on the files, but is that the time when the files were backed up, or when the files were last modified? What if you have two backups, both containing information you need?
With a git repository, you can simply ask. And you can synchronize changes between one or more git repositories, even if changes were made at different points in time. And you can do it with freely available tools. Again, Giterary isn’t a backup tool, but it can make putting the pieces back together much less daunting.
While storing metadata for changes to wording may seem like information overload, you can ignore it until you absolutely need it. The nice thing about Giterary is that it gives you a place to do these things while letting you focus on just writing.
Why would I need to organize my information this way?
Sure, everyone has their own way to deal with their information. But there are a few nice things to the way Giterary deals.
Text files abide by the law of least surprise.
Text is text is text. Files are files are files. Directories are, well, a bit more complicated, but you see what I mean. File formats change, features come and go, and registration keys get lost. Text files are the most basic way to store your information, and frankly, are hard to screw up. Most important: vast arrays of editing tools are available (far grander than Notepad), and are available everywhere you will ever turn on a computing device. You will never have to hunt down a copy of proprietary software that supports your file format (Word), nor worry that other programs won’t support the features of the one you wrote in.
You maybe should be dividing up your novel anyway…
Just saying. Why wouldn’t you try to divide out the pieces of your work into separate files? Or organize your reference documents and glossaries and appendices in a structured way?
The reason I can think of for not doing so is because eventually you’ll have to stitch them back together. This is easy for a computer to do, so why can’t you work on your smaller pieces, then tell the computer to put them together when you’re done? Giterary supports this, both in partitioning out documents into smaller files, as well as automatically creating “collection” files to stitch them back together. Plus, you can modify your collections to change the order of your documents without changing the underlying documents.
A wiki lets you create information and an interface to it at the same time
This sounds strange, but you see it every time you visit Wikipedia. The content of a document is well and good, but it’s the links within a document that lead you to the most interesting things. With a series of wikilinks, you can turn a normal document into a navigational structure. You can build chapter lists, character sheets, TODO lists, glossaries, indexes, whatever you want. And you can do it using the same syntax you use to write your story.
But what about the Otaku-Neckbeard-Hacker crowd?
I’m not a writer, though I once had hopes and dreams. I am, instead, a programmer who likes words and how they go together. I know writers, though, and editors, too. Though my fervor for the nerdier portions of this project burns bright, their practicality and intolerance tempered Giterary into a finer steel.
That said, there are still some things in here for those who share my mindset and my apathetic facial hair.
Minimal system requirements
The application requires PHP, a web server to serve the PHP scripts, and the git executable. Nothing else. Everything is self-contained. Everybody fights, nobody quits.
A simple codebase. The kind you’d like to start with, but not have to build yourself.
Do you like learning an entirely new object model every time you need to modify a project? A grand new set of design decisions and limitations that were made without you, and never documented? Me neither. Use of OO in the PHP backend is limited, preferring a series of functions that wrap around git CLI functionality and display logic. Need complex, stateful logic for something? Great. I hope my functions help when you wrap them into your objects.
There’s a simplistic templating engine, a few performance tracking modules, and some file caching, but nothing special. Everything is PHP, Javascript, and CSS, with the necessary parsing and rendering libraries included (Markdown, Showdown, jQuery, Tablesorter, etc.).
Edit how you want, git how you want.
Don’t like the Giterary interface? Prefer Notepad++? TextMate? SublimeText? Vim? Emacs? Something with an even greater sense of vague technological elitism? Great! Edit with that. I won’t be sad. Edit locally, and upload via your git client. That is, whichever of the dozens of beautiful, full-featured git clients roaming the wild. There is a git post-receive hook that will keep your web application up-to-date, but you can do with it as you like. Decide you hate Giterary and want to set up shop elsewhere? Certainly. It’s git, and it’s files. Go nuts.
Okay, but can you do anything to sweeten the deal?
Um, sure? I wasn’t going to mention, but since you asked…
CSV file support, with client-side sorting, default sorting hints, and wikilink syntax, perfect for establishing that timeline of geological events in your world, cross-referenced and tagged according to the events in your novel.
Being able to show which reversions, which author, and on which date every line of a file was last touched (called “blaming” in git-tongue). Every line. We don’t skimp.
Don’t particularly care for your editor’s last few edits? Well, reconcile your professional relationship by cherrypicking their edits ("canceling” or “restoring” edits, word by word). After you’ve corrected their obvious errors, drop the results into your editor to really show them the meaning of artistic license!
Trying to balance dialog versus exposition? Giterary’s dialog highlighting detects common “talk-y” looking quotes segments and can highlight them apart from normal text.
Keep forgetting what’s left to do? Insert a “TODO” line in your document, and then come back to it later from a specialized “TODO” search.
Need to shove a bunch of things into one document? Don’t feel like copy-pasting a bunch? Good! It’s because you should never do this to begin with. Create a document collection, allowing you to render any Giterary files, in any order, and according to each file’s specific rendering mechanism (Markdown, CSV, Text-only).
Have a massive manuscript you need to split apart into workable segments? Document partitioning will allow you to load a document, select “partition boundaries,” and even name the new partitions ("Chapter 1,” “Chapter 2,” etc.). It’ll even create a new collection to provide a way to stitch your original document back together.
Annotate documents and be able to “mouse over” the notes, but only when in “Decorations” mode. In fact, Giterary won’t try to “decorate” your document in any way (past your specified formatting) unless you tell it specifically to “Decorate” a document. Nothing is more offensive than somebody else’s bad decorating choices.
Annd… ah, well… you can search for things? Searching is fun. There is a search. And you can navigate your directory structures! It’s an adventure all to itself.
(Side note: It can also do things like show you dictionary word counts, auto-generating tables of contents, auto-saving drafts, etc., and other common word processing features, but those are pretty run-of-the-mill, so you can discover those for yourself.)
Whether by pity, morbid curiosity, genuine interest, or an intersection thereof, I feel compelled to give it a chance…
That strange compulsion is your keen technological and creative intuition talking. It means he or she is proud of you for getting this far. I, of course, never doubted you for a second.
From here you can:
- View the installation instructions. They’re a little involved, but not insurmountable.
- Look at the help file to get a sense of how to use Giterary (it’s not too bad).
- Kick around on the playground to see the application in its full glory.
- Check out the Frequently Asked Questions.
--
Thanks for reading. Happy writing!
authorbias
INSTALL
Installation Instructions
The following are general guidelines to getting Giterary running. These instructions are biased towards the Linux side of things, but there is no reason an enterprising individual couldn’t get them running on Mac OS or Windows. They also assume you have a basic working knowledge of the components of the Internet, how to configure your systems to run “services” or “daemons,” or a certain quantity of patience and a willingness to Google something if you don’t understand it.
Requirements
A computer capable of running PHP 5.3 or greater and git 1.7.X.X or greater.
These are widely available from many different Linux distribution packaging mechanisms (Debian and Ubuntu’s apt-get, Centos and Fedora’s yum, etc.) Binary packages are also available from their respective sites for all operating systems.
Web server software that supports running PHP
Numerous pieces of web server software support the use of PHP. Popular choices include:
- Apache (Available on Linux, Mac OS, and Windows)
- Nginx (Available on Linux, Windows, probably Mac OS)
- IIS (Windows) (Available on Windows)
You may not feel up to installing and configuring these yourself. I know: I’ve had those days, where the weight of the world dictates that you won’t look at another config file. But don’t despair: these are so popular and ubiquitous that many people sell services, construct virtual machines appliances, and make a ton of tools so that you can get off the ground with a web server and PHP easily. So much so that they’ve even given these types of setups a clever acronym: LAMP or WAMP ("Linux/Windows, Apache, MySQL, and PHP", minus the MySQL in our case). Do a couple of Google queries for “LAMP server” or “LAMP appliance” and you’ll see what I mean: tons of step by step guides, virtual machine appliances, and hosting services, all waiting for your time and patience (or money, potentially).
Unfortunately, those steps are beyond the scope of this document. We provide verification steps later here to make sure things are working, but getting to that point has been documented and solved much better by smarter people than the author of this document. No matter if you’re installing on your daily-driver laptop, or a fully-redundant cloud server, I would invite you to learn about such things, as they are valuable things to be knowledgeable about, will teach you about the underpinnings of the Internet at large, and makes you a blast at parties).
OPTIONAL: An SSH server program (if you are doing git-over-SSH synchronization, which is recommended)
git has the ability to push and pull from multiple sources, and using multiple network protocols. The most reliable and conventionally accepted appears to be SSH, which provides encryption as well as authentication. If you plan on “synchronizing” another computer with your Giterary instance, you will want to have an SSH server or git-capable equivalent to provide access to your Giterary repository.
- OpenSSH is widely supported on Linux, Mac OS, and on Windows.
OPTIONAL: A git GUI client
You will need the command line git client installed. However, there are a number of GUI clients (graphical user interfaces) that are a lot more friendly to human eyes.
It is highly recommended that you keep a git client handy, just in case you don’t like how Giterary does something, or that you have to do something Giterary doesn’t. These tools let you interact with your Giterary repository in lots of nice ways. They also provide a more forgiving git learning tool than the command line, man pages, and frustrated Google searches. I recommend the following:
- TortoiseGit (for Windows)
- SourceTree (for MacOS)
These requirements may seem out of control, but they’re not so bad, and in fact, are pretty common among web applications (though hidden by the fact that you only need a web browser to use them successfully). I can give a few recommendations, pointers, and places to get started with hosting your own Giterary instance.
(I’ll always advocate running your own servers before “going to the cloud.” It means that you own your hardware and your data, and you have to worry slightly less about how your novel will fare after the zombie apocalypse. However, starting from scratch, the learning curve for “rolling your own” is admittedly steep and having other services available to jumpstart your progress is too useful to leave it unmentioned. Plus, setting up and maintaining highly redundant, highly available server hardware is expensive and time consuming, and some people just don’t value geek cred as much as I do :) )
Here are a few things to look into if you’re a) installing your own server, b) exploring options for your own server, or c) curious about how to become a hit at parties:
- Ubuntu happens to be my favorite “I don’t care about the details, I just want to use something” flavor of Linux. Its package system tends to have everything, and if you’re wanting/needing it, it has a well-supported desktop environment, and a large user community.
- Amazon’s EC2 (Elastic Compute Cloud) is a cheap and quick way to get hosted in the “cloud,” and they can bill at cents per hour, if you’re wanting to be economical.
- TurnKey Linux is a collection of tested, pre-configured virtual machine appliances that can get you set up and running with what you want in just a few minutes. They have a pre-configured LAMP stack, and partner with Amazon’s EC2 to provide cheap virtual machine hosting on their Turnkey Hub service.
- prgrmr's tagline is “We don’t assume you are stupid.” Which is pretty great. However, they aren’t for the faint of heart. In fact, you may or may not have to send in a photo of your neckbeard for verification before you can be sold anything.
Another option is to call up or email that computer-savvy person you know, or, make friends with one you don’t. Honestly: we live for this stuff. Memorize the following phrase (phonetically, if you have to): “I want to set up an Apache server with git and SSH, and have it sync with my laptop.” If you work in a business that has an Information Technology department, you can walk into the middle of their work area and shout that above the server noise. Any geek worth their salt will venture out of their cube to ask further questions. Best case: they set it up for you. Worst case: you learn who to talk to next time something is really broken.
There are also Linux User Groups in pretty much every major city, state, and university campus. They like to be able to serve their community, and installing something like Giterary is an easy and straightforward task for them.
Latest Version
Grab the latest version of Giterary from:
HTTP Download
TODO: Hosting?
git clone
TODO: Github? Bitbucket?
Verify PHP versus Your Web Server
Every web server has a directory into which you can put files, and it will serve those files, for better or for worse.
Much of the configuration headache for web servers is getting the names, access rules, and pointers to the right directories into place. We leave it up to the reader to maintain their own security, but take heed when we say that the intent of a web server is to put things on the Internet. Be sure that you check to see if things are exposed that should not be (for instance, if your Giterary instance is exposed to whoever happens to be sitting next to your at the airport terminal).
Most important to establishing this “hosted directory” is ensuring that PHP is configured correctly. Within your “hosted” directory, place a file called test.php, which has only these contents.
<? phpinfo(); ?>
Afterwards, using your web browser, browse to a URL referencing your host and the test.php file, for instance:
If you plan to be accessing Giterary from only your own machine:
http://localhost/test.php
If you are installing to a separate server:
http://myserver/test.php
If you are installing Giterary to a place other than the URL’s “root” (referring to the “/giterary/” portion of the URL not being at the “root” of the path after the myserver host specification.)
http://myserver/giterary/test.php
This page should contain an output from the phpinfo function that lists all of the compilation, configuration, and dependency information for your PHP installation. It will be purple.
If this is running successfully, then you have a working PHP configuration for your web server. Good job!
The Easy Way, or The Hard Way (install.sh)
There is Linux install script that tries to walk you through your various configuration necessities (names, paths, usernames, passwords, etc.). It isn’t particularly sophisticated, and isn’t particularly platform agnostic (has only been ran on Ubuntu), but it’s a lot easier than wading through all this mess.
It is located in the root directory of the source code, called install.sh.
If successful, it sets you up with a Giterary instance with:
- A working git repository
Reasonable directory structure for git repository, cache, temp, draft, and session information:
/var/lib/giterary /var/lib/giterary/repos/your_repo_name /var/lib/giterary/caches/your_repo_name /var/lib/giterary/temps/your_repo_name /var/lib/giterary/temps/your_repo_name/drafts /var/lib/giterary/temps/your_repo_name/sessions
Initializes your git repository, sets an anonymous user for the repository (required from operating from a web application like Giterary), and other small git repository configurations.
- A “passfile.csv” configuration, where a special CSV is added to Giterary that contains your username, git user information, and hashed password (pointed to with the config/auth.php config file). It is then configured as a “sensitive” file that only only be edited by the username your enter (with the config/permissions.php config file).
- Adds your DEFAULT_FILE to the repository with a welcoming message.
This is a fairly straightforward and secure configuration out of the box.
Verify Git Is Working
From your operating system’s command line (any terminal in Linux, Terminal in MacOS, the cmd MS-DOS prompt in Windows), attempt to execute the following command.
git --version
It should print out something like this:
git version 1.7.4.1
Alternatively, if your environment paths are somehow incorrect, you may need to be explicit in the path to your git executable.
To find your explicit path on Linux and MacOSX, you can issue the following command:
which git
…which should return the explicit path. In my case, it returns this:
/usr/local/git/bin/git
On Windows you may have to search the filesystem for git.exe and use the explicit path it returns.
With your explicit path, run the following command (but with your explicit path):
/usr/local/git/bin/git --version
This should give you version information for your installation of git.
Verify the security configuration on your system for your git client. It needs to be executable by the user that is running your web server. This is critical for Giterary to function.
Note this path value, as this is the path you will need to use later in the Giterary configuration.
Create Giterary directories
Giterary needs a few directories to run:
The directory of the git repository.
This is a directory that will need to be readable/writable, and will store the git repository and its working directory. Recommended locations:
Linux or MacOSX:
/var/lib/giterary/repos/NAME_OF_YOUR_REPO
On Windows:
c:\programdata\giterary\repos\NAME_OF_YOUR_REPO
The directory for Giterary to store “cache” information to make the application speedier.
This is a directory that will need to be readable/writable, and will store the Giterary cache files to help make browsing via Giterary speedier. Recommended locations:
Linux or MacOSX:
/var/lib/giterary/caches/NAME_OF_YOUR_REPO
On Windows:
c:\programdata\giterary\caches\NAME_OF_YOUR_REPO
The directory for Giterary to store “session” information that allows you to be logged in to the application.
This is a directory that will need to be readable/writable, and will store the PHP session files that allow you to log in. Recommended locations:
Linux or MacOSX:
/var/lib/giterary/sessions/NAME_OF_YOUR_REPO
On Windows:
c:\programdata\giterary\sessions\NAME_OF_YOUR_REPO
The directory for Giterary to store “temp” data, like draft files and file comparison inputs.
This is a directory that will need to be readable/writable, and will store the PHP session files that allow you to log in. Recommended locations:
Linux or MacOSX:
/var/lib/giterary/temp/NAME_OF_YOUR_REPO
On Windows:
c:\programdata\giterary\temp\NAME_OF_YOUR_REPO
These locations are relatively arbitrary, and you could potentially combine the cache and session directories into one (but never the repository directory, that must remain apart from everything).
Oh, the config files…
There are a series of configuration files necessary to getting Giterary up and running. They are all PHP files, and can be edited using any text editor. They are located within the include/config/ directory of the Giterary source. They are situated such that one could have multiple instances of Giterary, but with different include/config directories, and the instances would be able to run simultaneously.
base.php
base.php
base.php is the largest configuration file, as it contains references to the most basic portions of Giterary that are necessary to run ("Where is my repository?", “What is my name?", etc.). Below is a line-by-line description of the configuration values within base.php.
The following are required fields.
SITE_NAME and SHORT_NAME are display values for showing on the Giterary interface which instance of Giterary is running. This is where you put a name for the “title” of Giterary.
define('SITE_NAME', "My New Story"); define('SHORT_NAME', "New Story");
The BASE_URL is the base HTTP URL that will be used to navigate to your Giterary instance. This is used in link generation.
define('BASE_URL',"http://myserver/giterary/");
The DEFAULT_FILE gives the name of the first file to be created within your Giterary instance, and the default file to be displayed when no file is specified (likely the first file that will be displayed with accessing your Giterary instance).
define('DEFAULT_FILE', 'Home' );
SRC_DIR is the filesystem location of the source files for Giterary.
define('SRC_DIR',"/var/lib/wwwroot/giterary/");
GIT_PATH is the filesystem path to the command line git client on your server.
define('GIT_PATH',"/usr/local/bin/git");
GIT_REPO_DIR is the path to the readable/writable directory that contains the git repository for this instance of Giterary.
define('GIT_REPO_DIR',"/var/lib/giterary/repos/NAME_OF_YOUR_REPO/");
CACHE_DIR is the readable/writable directory for maintaining caches of certain data within Giterary.
define( 'CACHE_DIR','/var/lib/giterary/caches/NAME_OF_YOUR_REPO/' );
CACHE_ENABLE is a value of 1 or 0, 1 being that use of the cache is enabled, 0 is that it is disabled.
define( 'CACHE_ENABLE', 0 );
TMP_DIR is the temporary directory for temporary files generated by Giterary. It can be under the same directory as the Giterary cache.
define('TMP_DIR','/var/lib/giterary/temp/NAME_OF_YOUR_REPO/' );
DRAFT_DIR is the directory for storing draft files within Giterary. It can be under the directory as the Giterary cache.
define('DRAFT_DIR','/var/lib/giterary/temp/NAME_OF_YOUR_REPO/' );
SESS_PATH is the directory for storing cookie information for interacting with your browser.
define('SESS_PATH', '/var/lib/giterary/sessions/NAME_OF_YOUR_REPO/');
The following are optional fields.
STYLESHEET and CSS_DIR are relative URL references to the default CSS to be used by the Giterary application.
define('STYLESHEET', "simpler.css"); define('CSS_DIR', "css/");
The following are variables for configuring cookie information for communicating login session information with your web browser.
define('COOKIE_DOMAIN', 'www.YOUR_DOMAIN_HERE.com'); define('COOKIE_PATH', '/'); define('COOKIE_EXPR_TIME', 86400); define('SESS_NAME', 'GITERARYSESSION');
permissions.php
permissions.php and permissions.lib.php
permissions.php is the configuration file for how users are permitted to perform certain actions within Giterary. permissions.lib.php is a set of common permission settings, defined as named classes, and usable as objects to be “registered” within permissions.php.
A common, starting instance is “AllPlay", where all users can perform all functions without limit.
<? require_once( dirname( __FILE__ ) . '/permissions.lib.php' ); $registered_auth_calls = array(); register_auth_call( new AllPlay(), "can" ); ?>
For a more “private” Giterary experience, the MustBeLoggedIn class defines that in order to view any portions of the site, you must have successfully logged in to the site.
<? require_once( dirname( __FILE__ ) . '/permissions.lib.php' ); $registered_auth_calls = array(); register_auth_call( new MustBeLoggedIn(), "can" ); ?>
For a “mixed” Giterary experience, SensitiveFiles allows you to define certain files which are considered “sensitive,” in that you must belong to a set of defined users otherwise you can neither read nor write to the files.
<? require_once( dirname( __FILE__ ) . '/permissions.lib.php' ); $registered_auth_calls = array(); register_auth_call( new SensitiveFiles( array( "passfile.csv" => array( "jrhoades" ) ) ), "can" ); ?>
auth.php
auth.php and auth.lib.php
Similar to permissions.php and permissions.lib.php, auth.php and auth.lib.php provide the configuration and the common case library for defining how people log in to Giterary. Essentially, how the user list is determined, and how passwords will be stored.
Currently there are two common configurations, StaticUserList and PasswordFile.
In a StaticUserList configuration, a class is defined in auth.lib.php that describes the user list, their properties, and their passwords. Editing the StaticUserList class in auth.lib.php is necessary for this configuration. This method is not necessarily recommended, though, is common due to the ease of maintenance.
<? require_once( dirname( __FILE__ ) . '/auth.lib.php' ); $registered_login_calls = array(); register_login_call( new StaticUserList(), "validate_login" ); ?>
In a PasswordFile configuration, a CSV is referenced that defines username, user git properties, and a hashed password. This file can exist within your a repository (and be editable from the Giterary interface), or be outside of your repository and be edited manually, it is up to your security requirements. A permissions.lib.php class is defined specifically for this type of file called “SensitiveFiles,” which requires specific user credentials to be able to edit a file.
<? require_once( dirname( __FILE__ ) . '/auth.lib.php' ); $registered_login_calls = array(); register_login_call( new PasswordFile( '/var/lib/giterary/repos/my_repo/passfile.csv' ), "validate_login" ); ?>
A “passfile” is a CSV formatted file that contains names, emails, and password information for users to log in with. An example file might look like this:
Username,GitUser,Password jimmy,"Jimmy <jimmy@jimmy.com>",6f1ed002ab5595859014ebf0951522d9
The file is a CSV, and as such, can be edited using the Giterary interface (and will render as a table when viewing). However, you don’t want just anyone on your Giterary instance viewing and/or editing your password file. In these cases, you want to use permissions.php to flag your passfile.csv as “Sensitive,” and only viewable/editable by a small set of users.
WARNING: Just because the Giterary interface restricts access to such a file doesn’t mean that people with access to your git repository won’t. Anyone who can read information from git can read your passfile. While efforts are taken to make sure your passwords are obfuscated, it’s important to know that git itself doesn’t do “security.” If you want to use a passfile, but not have the file be located in your git repository, simple move your passfile to somewhere that isn’t in your git repository. You will have to edit this file by hand.
Finally, you might be asking yourself, “Who wants to enter in ‘6f1ed002ab5595859014ebf0951522d9’ as a password?” The answer is: absolutely nobody. Nor do they. This is a “hash” of your password, a mathematical algorithm performed on your password to make it difficult to guess its original contents. When you log in to Giterary, the password you enter is ran through this same algorithm, and if the two “hashed” results are equal, you have successfully entered your password and you are allowed to log in. It’s a clean and useful way of storing passwords without having to store them at all.
However, the question becomes how to generate these password hashes. On Linux, the following commands are available:
md5sum sha256sum sha512sum
…And others, which let you pipe in arbitrary text (ie, your password) and return a hashed result. For example, for the password “blah” (which is a terrible password which you should never use):
echo -n "blah" | md5sum
…will return the following:
6f1ed002ab5595859014ebf0951522d9 -
NOTE: You must include the “—n” portion of the echo command, otherwise echo will emit a newline character, which will invalidate your hash value.
The 6f1…22d9 value is what you paste into your Giterary passfile.csv. However, Giterary assumes that unless you specify your hashing algorithm, it will just use the MD5 algorithm. This is fine if you only ever generated hashes with MD5, but some people want a more cryptographically hardened hash value. If you want to do a SHA256 hash, you would have to put in the following:
"sha256$8b7df143d91c716ecfa5fc1730022f6b421b05cedee8fd52b1fc65a96030ad52"
Or, for SHA512:
"sha512$39ca2b1f97...(long, long result )...1c2fa54b7"
The important part being the “xxxx$” prefix. Anything before the “$” in the password fields is treated as a hashing hint, to suggest to Giterary which hashing algorithm is used. The “xxxx” hash hint can be anything that is supported by PHP’s hash() function.
dict.php
dict.php
The dict.php file defines the path to the “dictionary” file, as well as sets of configurable groupings of words for calculating document metrics (the “Statistics” page).
DICTIONARY_PATH is the path to a file that consists of 1 word per line. On Linux, this path is normally /usr/share/dict/words.
define( 'DICTIONARY_PATH', '/usr/share/dict/words' );
The following are the lists that define the groupings for which words are to be considered conjunctions, “non-counted” words (common words you don’t want counted as “words” for your stats), past tense verbs, and present tense verbs.
$conjunctions = array( /* ...for, and, not, nor... */ ); # http://en.wikipedia.org/wiki/Most_common_words_in_English $non_counted_words = array( /* ...the, be, to, of... */ ); $past_tense_verbs = array( /* ...was, wasn't, did, didn't... */ ); $present_tense_verbs = array( /* ...is, isn't, am, are... */ );
perf.php
perf.php
A flag for whether to calculate performance stats and include a “performance report” in the HTML comments of every Giterary page. Enabled by default.
<? define( 'PERF_STATS', 1 ); ?>
time.php
Defines the default timezone to be used when making changes from the Giterary interface.
<? date_default_timezone_set ( 'America/Anchorage' ); ?>
conventions.php
The conventions.php file defines the basic “conventional” assumptions Giterary makes when defining things. Examples of conventions are:
The suffix used for “dirified” directory names (dir by default).
define( 'DIRIFY_SUFFIX', "dir" );
Default character encoding for the Giterary instance (UTF-8 by default).
define( 'ENCODING', "UTF-8" );
Regular expressions to determine the valid filename and file path patterns used on the site.
$wikiname_pattern = '-_a-zA-Z0-9\.\s'; $wikifile_pattern = "@^([$wikiname_pattern]+)(\\/[$wikiname_pattern]+)*$@"; $wikilink_pattern = "@(\\\)?\[\[([$wikiname_pattern]+(\\/[$wikiname_pattern]+)*)(\|([\w\s\.\,\\/-]+))?\]\]@"; $functionlink_pattern = "@(\\\)?\[\[([a-zA-Z]+):(([^\]|,]+=[^\]|,]+)(,[^\]|,]+=[^\]|,]+)*)?(\|([\w\s\.\,\"/-]+))\]\]@";
html.php
html.php
html.php defines parameters for dealing with the HTML generation within Giterary.
The $allowed_tags configuration variable defines which tags are allowed to be used for final rendering within Giterary.
$allowed_tags = array( /* ...'<p>', '<h>', '<pre>', '<img>', '<table>'... */ );
The default list provided with Giterary is a good subset of HTML which provides a wide range of HTML dipslay elements while avoiding potential security risks by disallowing the inclusion of Javascript from a page. You, however, may want to change this at some point, which is entirely up to you and your security requirements. However, this is by no means recommended, and likely will be more of a pain to manage than the functionality gained by allowing such features to be embedded within documents. Proceed at your own risk.
themes.php
themes.php
themes.php defines the names and paths responsible for rendering the various pieces of Giterary. This file is not necessary to edit in an initial configuration, but is important if you want to add your own elements as “overrides” to the default theme.
DEFAULT_THEME is the name of the “default” theme to be used for your Giterary instance. This theme must be the name of a array key within the $themes configuration variable later on (and is by default).
define('DEFAULT_THEME', 'default');
The $renderables array is a list of name-to-path associations for ‘well-known’ renderable files, responsible for rendering anything from page layouts to reusable widgets or error messages withing Giterary.
$renderables = array( 'default_layout' => 'theme/default/renderable/layout/standard.php', 'edit_layout' => 'theme/default/renderable/layout/edit.php', 'show_layout' => 'theme/default/renderable/layout/show_layout.php', 'note' => 'theme/default/renderable/note.php', 'gen_error' => 'theme/default/renderable/gen_error.php', 'gen_header' => 'theme/default/renderable/gen_header.php', 'gen_history' => 'theme/default/renderable/gen_history.php', /* ... */ 'not_logged_in' => 'theme/default/renderable/not_logged_in.php', 'gen_csv' => 'theme/default/renderable/gen_csv.php' );
The $themes array defines as the keys the names of available themes, and as the values of those keys, arrays that describe “overrides” of the $renderables definitions for the named renderables. This allows a theme author to make as much use of the default theme as possible, and only define their theme as “exceptions” to the default theme as necessary.
$themes = array( 'default' => array(), );
Note again that editing this file is not required, but we’re just providing a description here for documentation purposes.
Initialize your git repository
Your git repository needs to be “primed,” so to speak, before being used by Giterary. First off, within your repository directory (perhaps /var/lib/giterary/repos/your_repo), do the following command:
git init
This will initialize an empty directory for you to work with (and creates the “hidden” files that git uses alongside your own).
You also need to inform git “who you are,” though, this isn’t really your name, as the Giterary application provides your committing information for you. However, git still squawks when this is unavailable. To silence this, we set a temporary, “anonymous” user for the repository. The name doesn’t particularly matter, nor does the email address have to be valid.
git config user.name "Anonymous User"
git config user.email "anonymous@anonymous.com"
(Once the Giterary authors figure out how to get around this, we will likely be able to skip this step.)
That was horrific. Am I done?
Well, I think so. At least the Giterary part anyway. You should browse to your Giterary instance with your web browser, loading up index.php to see if it displays the editing screen for the file indicated by the file name configured with DEFAULT_FILE in base.php.
http://localhost/giterary/index.php
If the page loads, and you’re able to save your file successfully, then you’ve succeeded in installing and configuring Giterary.
It didn’t work. I have shamed myself and my family.
No! Not at all. We are human, we must err, or, do things which cause error messages.
As we get more people performing installations we will include “common” errors and hopefully provide reasonable solutions.
Optional Pieces
I say “optional,” but really I mean “very cool, but if it’s already 2am and you’ve got stuff to do in the morning, it’s alright if you come back later.”
The following are the cool things around which Giterary was based: being able to use your own favorite editing tools, and being able to synchronize from any source, and in any direction.
Being able to push/pull from Giterary
I can’t recommend enough being able to push and pull from a setup external to the one running your Giterary instance. This is bread and butter of why you would use git for something like this in the first place. Unfortunately, unless you’ve worked with a version control system before, or have written programs collaboratively before, it’s unlikely that you’ve been a part of this kind of workflow.
The first part of being able to push/pull using git is probably to learn more about git itself. There are a ton of sources out there to learn how to use Git.
- gittutorial, git’s own tutorial (admittedly dense).
- git-scm’s documentation and videos, particularly their “Distributed Git” section
- Github’s 15 minute tutorial
Honestly, I learned git by way of Googling, man pages, and more furious Googling. The resources are out there. Stackoverflow is rife with questions on git and its usage, and usually has great answers for some of the more subtle use cases around git. They may not be obvious, and the verbs are sometimes a little odd, but there are some amazing things you can do with git. Pushing and pulling is just the start.
What you first want to be able to do is use a git client to be able to clone your Giterary repository, and use it as one of its “origins.” From there, you can see your Giterary files as they truly exist: in files and folders, named as close as could get to how they’re represented in Giterary.
From there, you can open any file in your git repository working directory in your favorite text editor. You may or may not have the live-preview of Markdown, or whichever file format you’re editing, but you also have a suite of tools available to you that are difficult or otherwise impossible to do from a web interface (multiple selections, column edits, search and replace, pattern recognition, intelligent spellchecking, etc.).
Save the file, and then use your git client to “commit.” This is an important step in the git workflow. Committing to your repository informs git that “Yes, indeed, I intended to make those changes, and I think I’m ready to save these.” Certain git clients smooth this over, informing you of changes and automatically adding them to your commit, which saves a bit of time. However, “true” git considers your working directory to be just that: a work in progress. It may be that you aren’t done yet, but you may have portions of your work you want to commit. Or, you can stage your changes and swap out your entire working directory to focus on something else entirely. git, like Giterary, tries to help you with the hard stuff, but also tries to get out of your way when you just want to work.
After committing, you can “push” back to your Giterary origin. Depending on your Giterary setup (and the presence of your post-receive git server hook (as described later), you should see your updates reflected in the Giterary interface. If not, be sure that you clear the cache of the edited documents in question.
Post-receive git server hook
git gives you the ability to push and pull from whatever repository you like. A recommended setup with Giterary is to synchronize a copy of your Giterary repository to a separate computer (your daily driver laptop, etc.), and synchronize via SSH.
This creates a problem, however. Potentially, you can push to your Giterary server repository, and while your push may succeed, the files in the working directory on the server may be out of sync.
To solve this, we use a feature of git called “hooks.” In particular, there is a hook called the post-receive hook, which allows you to perform arbitrary user action on the server after successfully receiving your commits.
Put the following into /path/to/your/repo/.git/hooks/post-receive to enable this feature:
#!/bin/bash
echo "Refreshing server's working tree";
/usr/local/bin/git --git-dir=/path/to/your/repo/.git --work-tree=/path/to/your/repo/ reset --hard;
exit 0;
Additionally, git takes issue with pushing into non-bare repositories. While normally this would be for good reason, Giterary needs to be able to push into a non-bare repository in order to synchronize its files for display on the Giterary interface.
git config receive.denyCurrentBranch ignore
HELP
Giterary User Manual
The following document is a user’s manual of sorts for day-to-day user interaction with a working Giterary instance. If you’re having issues with configuration or installation, you should look at the INSTALL document.
This document takes you through basic understanding of the function of Giterary as a wiki, how to navigate and interact with document objects within the application, and how to create, modify, and view the change history of them.
Giterary Concepts
Giterary belongs to a family of computer software that calls themselves “wikis.”
What is a wiki?
A wiki is an application that lets you navigate and edit a web of documents and document references from a single interface. The most famous wiki being “Wikipedia.” You may have heard of them.
Wikis are powerful tools because they allow you to efficiently organize and navigate your information while providing multiple users the ability to update and maintain the content. They vary in ubiquity and in features, given special use cases, extensibility, and popularity. Giterary’s wiki features are inspired largely by Mediawiki and MoinMoin (both excellent examples of full featured and extensible wiki software).
File Structures and naming
Giterary employs a hierarchical structure to its file naming conventions, allowing for the user to organize their file content in logical folder structures while being relatively lax with regards to file name formats (compared to other wikis).
Naming Files
File names can include almost any normal filesystem character (alphanumerics, slash, underscore, spaces) minus a colon (":"), slash or ‘solidus’ ("/"), and non-printing characters (newline characters, etc.).
Like files on your computer, all files exist within directories. You can choose to operate without directories, but this guide recommends you take advantage of this feature in order to organize your content.
All files can be referenced using a file path. This file path refers to the “path” one must traverse through the directory structure of your Giterary repository in order to get to your actual file. Examples would be like the following:
Home (the "home page" for your wiki)
bobby (the "user page" for the user "bobby")
My Story/Chapters/Chapter1 (Chapter 1 of many chapters of "MyStory")
bobby/jot/2013/01/19-Sat (user bobby's "jot" for 2013/01/19)
Files, Directories, and “Dirification”
There comes a dilemma when creating a hierarchical wiki document naming scheme.
Let’s say you have a directory structure like this:
My Story/Chapters/Chapter 1
My Story/Chapters/Chapter 1/Notes
My Story/Chapters/Chapter 1/Citations
The question becomes: What type of object is the thing called Chapter 1?
Chapter 1 is certainly a file, but it’s referred to in the paths to Notes and Citations as a directory path component.
Giterary solves this problem with the concept of “directorification” or “dirification.” It is an abuse of file paths to make it seem like Chapter 1 is both a file and a directory. By way of “dirification” Giterary will treat the following two file paths as equivalently referencing the exact same file:
My Story/Chapters/Chapter 1/Notes
My Story.dir/Chapters.dir/Chapter 1.dir/Notes
In the first file path, it is implied that the path components My Story, Chapters, and Chapter 1 have the suffix “.dir” appended to them because they are being treated as a directory. In the second file path, the “.dir” suffixes are explicit, but refer to the true, “dirified” path.
In this way, there can still be two objects with the “same name,” but only by a quick sleight of hand on Giterary’s part. In this way, you can ask to edit My Story/Chapters/Chapter 1 and My Story/Chapters/Chapter 1/Notes and have it do the right thing.
Relative Paths
While descriptive, it is sometimes tedious to detail the full path for a file. Given a large or complicated enough structure (or even just a lengthy directory or file name), having to specify the full path to something can be redundant. This can also be a pain when file or directory renames occur, as the file links prior to a structural move can be broken (and usually as great scale, given how many files were moved).
To help with this, the concept of relative paths is available. These are useful to help your structures remain intact across renaming, as well as reduce repetition when creating document references. For instance, if you’re viewing the following file:
Working Title/Bookmaking/Book1
…It is possible to create a link with the path specified like so:
<a title="HELP/Act2/Scene3" class="wikilink" href="index.php?file=HELP/Act2/Scene3">Book 1, Act 2, Scene 3</a>
Note the ./
prefix at the beginning of the path. The ./
prefix refers to the current document being viewed/rendered, replacing the ./
with the path prefix Working Title/Bookmaking/Book1
. This is translated on the fly, and as it is relative to the document the link is generated from, it will survive a rename of your story from “Working Directory” to whatever you choose.
Another relative path function exists, which is to “go up” a directory. For instance, in the same Book1
document, one could have the following link:
<a title="HELP/Book2" class="wikilink" href="index.php?file=HELP/Book2">Next Book</a>
…which will translate the file path to be effectively the following:
<a title="Working Title/Bookmaking/Book2" class="wikilink" href="index.php?file=Working Title/Bookmaking/Book2">Next Book</a>
This ../
prefix can be repeated multiple times to “go up” as many directories as is necessary. However, note that you cannot “go up” past the root of the directory, and is considered an invalid path specification.
Relative paths can work where the question can be answered “What document am I viewing currently?” This means that all document links and all function links being rendered in a document can use relative paths rather than absolute paths.
Creating New Files and Directories
Per wiki software convention, the most common way to create a new file is to edit an existing one with a link to the new page, and then navigating to that link. Giterary tries to adopt this convention, erring on the side of good organizational structure rather than simplicity of just creating a new file. That said, there is nothing to stop a user from just looking at the URL of the file referenced in their browser window and change it to their desired new filename.
An alternate route exists, however: if you browse to any directory, a text input is available, pre-populated with a data structure relevant to the currently viewed directory, and something akin to NewFile appended at the end. This will allow you to easily create files under known directory structures.
Additionally, one can hit the “Jot” button when logged in, which immediately puts the user in the editor for a file that is date-stamped to the current date. This is another way to quickly write in a new file while retaining some information about when that file was created.
myusername/jot/2013/01/21-Mon
A final note on creating new files: if a new file references a path component that does not exist, when finally committing that file Giterary will create all necessary directories in order to place that file on the path specified. For instance, in a blank repository, edits and submits the file “My Story/Chapters/Chapter 5/Notes” it will create the following directories:
My Story.dir
My Story.dir/Chapters.dir
My Story.dir/Chapters.dir/Chapter 5.dir
File structures can be moved and deleted, so mistakes made during this process are not the end of the world.
Searching
The search bar at top left can search on both file name, file path, and file contents. The search page will indicate the type of match next to the search results.
There are also a number of ways that external portions of Giterary make use of the searching interface. For example, there are two special searches you can perfrom:
- From a given document display, you can select Other Options > Search for …What Links Here, and return all documents that have wikilinks pointing to this page.
- From the top navigation “TODO” hyperlink when logged in, you can view a list of documents that contain special “TODO” flags within them that indicate work needing done at certain parts of a document. These work for both “TODO” and “TBD” patterns found within documents.
Types of Objects within Giterary
There are some things to know about dealing with files, directories, and navigating them within Giterary.
File types are determined by extension
If a file has an extension (MyFile.txt, MyTable.csv, MyNotes.md, etc.) that extensions handling (as determined by Giterary) will be used by default when displaying the page (txt or text for purely textual documents, md or markdown for Markdown syntax documents, csv for Comma Separated Values formatted files, and so on).
For files with no extension (Chapter1, 01-Wednesday, HelpFile) a default renderer is chosen, and that renderer is configured to be the Markdown renderer by default. See later in this document for explanations of Markdown.
You can also override the renderer by specifying different “as=someextensionname” on the URL of a document. This is useful for rendering something as its underlying source code (as=text), readable text (as=wrap). For instance, this document as:
Directories are for browsing
On every document, there is a tab called “Directory” that will go to a page listing the contents of the directory with that document’s same “dirified” name. For instance, viewing My Story and clicking on “Directory” will list anything under the directory called My Story.dir.
This is useful for navigation your organizational document structures.
Document Decorations
In addition to the formatting provided by Markdown syntax and other HTMl formatting tags, Giterary also provides additional “decorations” to a document. These decorations are “hidden” by default, but are present in the Giterary interface by selecting the “Decorations” checkbox at the top of a document display, or by hitting the letter “d.”
The decorations currently available are:
- Annotations (described in the Editing section)
- Dialog highlighting (described in the Editing section)
- Invisible headings (these will be described in the Table of Contents section).
Document Tables of Contents
Giterary takes it upon itself to create a table of contents based on the elements within your documents. These help to navigate within documents (particularly in the case of large documents). In Markdown format, if you have a line that looks like this:
Header Title
------------
…or like this…
Header Title
============
…or like this…
## Header Title
…you have specified that there should be a “header” element with the text Header Title. This will generate the appropriate HTML element (the h1, h2, h3, h4, h5, or h6 tags) according to the “level” of header. Refer to the Markdown syntax documentation for more complex header generation.
Each of these header elements are then detected by Giterary upon rendering, and can be turned into “bookmarks” as part of an automatically generated table of contents. Depending on your screen geometry (window width of your browser), this table of contents will appear either at the top of your document, or to the right of your document.
Giterary makes one departure from Markdown’s normal “header” output, in that it treats the h6 (header level 6) elements differently. Rather than displaying h6 elements like the rest of the headers, they will be invisible, but still be treated as “bookmarking” elements. With this, you can treat h6 headings as invisible placemarkers within larger documents. This is useful if you want to maintain bookmarks within a document, but not disrupt the formatting of the document with headings.
For example:
###### This is a hidden heading
Will generate a This is a hidden heading table of contents item, but not render within the document (as you should not see below)
This is a hidden heading
As part of the decorations functionality, enabling decorations on a document with invisible headings will display the headings at their position within the document.
Comma Separated Values Files, or Tables (*.csv files)
A CSV file (Comma Separated Value) file is a file whose content consists of tabular data stored in a text document, with line of text representing a “row” of data, and different columns specified by a list of fields, separated by commas.
For example:
Year,Month,'Day of Month',Note
2013,01,18,'Today I drank beer. Perhaps I drank too much.'
2013,01,19,'Today I drank tea. It's not the same as coffee.'
These files will be rendered as dynamic tables within your document, like so:
Year | Month | Day of Month | Note |
---|---|---|---|
2013 | 01 | 18 | Today I drank beer. Perhaps I drank too much. |
2013 | 01 | 19 | Today I drank tea. It's not the same as coffee. |
These CSVs will assume the first row of data is “header” data. It will then put it in an HTML table that can be sorted by the user.
One can also specify default sorting methods with the following syntax:
- !Year sorts the column “Year” in least-to-greatest order.
- ^Year sorts the column “Year” in greatest-to-least order.
- !#Year sorts the column “Year” in least-to-greatest order, treating all elements as numbers.
- !@Year sorts the column “Year” in least-to-greatest order, treating all elements as strings.
You can mix and match the sorting “hints” as you wish, though, they will be evaluated from left-to-right in the header specification.
CSV tables can also be “included” with function links, using the function link syntax as follows:
<div><p><a title="MyTable.csv" class="wikilink" href="index.php?file=MyTable.csv">MyTable</a> [<a class="wikilink edit" href="edit.php?file=MyTable.csv">Edit</a>]</p></div>
This will include the MyTable.csv
in the current document without having to view it as part of a collection, or using the explicit HTML table syntax (table,th,tr, and td tags).
Collections
Collections have the purpose of rendering multiple documents within your Giterary repository at once. This is done as a special rendering of the collection or collect file extensions. Contents of these files are simply lists of other file paths (MyFile, Wherever/I/Put/My/File.txt).
For example:
/DarkAndStormyNight/Chapters/Chapter1
/DarkAndStormyNight/Chapters/Chapter2
/DarkAndStormyNight/Chapters/Chapter3
Will render the files Chapter1, Chapter2, and Chapter3 in succession on a single page. This is useful for stitching together a larger document (the entirety of a book, for instance), of which you have broken into smaller, more manageable pieces (chapters, in this case).
By editing the collection, you can re-order its component parts by changing the order of the paths referenced in the collection document. For instance, if you decided to put Chapter3 before Chapter 2:
/DarkAndStormyNight/Chapters/Chapter1
/DarkAndStormyNight/Chapters/Chapter3
/DarkAndStormyNight/Chapters/Chapter2
Time travel novels are notoriously difficult to write, but this should help to order your components without having to change the underlying contents.
You can also use the collection documents to include an entire subtree of your Giterary repository. For instance, for the user “jrhoades,” they may have a collection that contains the following:
jrhoades/jot/201*/*
Use of the asterisk wildcard lets you match all documents matching the collection query. Documents will be rendered in order of directory traversal, and in alphanumeric order. The above example will render all “jot” files for the user “jrhoades” for the years 2010-2019.
Collections can also specify “tags” (described [[HELP#Tags|later]]), which are ways to categorize and later search for documents. You can specify any number of tags to search for under a certain collection path specification, like the following:
/DarkAndStormyNight/*:~scene,~dark,~storm
This will match only documents that are tagged with ~scene, ~dark, and ~storm (excluding those that contain none, or fewer than all three of the tags).
Lists (.list files)
Lists are a functional counterpart to collections. While collections display a series of documents in their entirety, lists simply show which files are matched by a collection. Lists are a fairly powerful way to create dynamic interfaces based on the contents of your Giterary repository.
List files use the exact same syntax as collections, however, are rendered differently (as a matter of fact, any collection can be displayed as a list in the Other Options dropdown, or vice versa).
List files can also be rendered as sorted tables (much like CSV files), which helps to organize files (particularly if they are named in a way that can be sorted reasonably).
Talk pages
Similar to Wikipedia, Giterary tries to support discussion surrounding a document that does not take place within the document in question. However, rather than a different document namespace, we instead place a special file, called a “Talk” file. The only thing truly special about Talk file are that they are always named Talk.talk
, and that they just in the directory just “below” the directory in question. You can access or edit a talk file by choosing “Other” options, and hitting “Talk.”
By default, Talk files will be listed as “Talk:FILE", where FILE is the base name of the file they refer to.
Document Statistics
Document statistics are your basic “word count"—types of metrics that Giterary will calculate for you. For instance, you can view the statistics for this very help file.
Statistics calculations also work on collection files, such that the statistics will be calculated for the collection document after all of the components of the collection have been collected.
Document Import
A simple tool is available to “convert” content from other sources into Markdown. You can use it by selecting the “Write” menu, and choosing “Import into New Jot", or opening or editing a new file and choosing the same option under “Other.”
Partitioning
If you do manage to get your document into a textual format suitable for Giterary, it is likely that this document is sufficiently large (in the case that you’re submitting a manuscript, or something of that scale).
It may be the case that you want to split up this document into smaller parts for you, your co-authors, or your editors to work on. In this case, Giterary does have a tool for easily “partitioning” files that makes this type of organization much easier.
Partitioning works by finding “potential boundaries” by determining where there are blank lines (or lines with only whitespace) within the body of work. As these blank lines have no content, they are likely things like spaces between paragraphs, chapters, etc.
The partitioning interface presents these boundaries, and allows you to select which boundaries you want to use. It then provides you with a summary of your new partitions, and allows you to name according to the Giterary filename semantics.
To see an example, try to partition this file.
Document Editing
The editor
While logged in to Giterary, viewing any object (except for directories) there will be an “Edit” tab at the top of the document. This link will take you to an editor for that particular page. An editor does generally what you expect: it shows you the text contents of a file, and allows you to modify the contents, and save your changes. There are, however, a few things to note about the editor.
The editor is contextually aware.
That is, the editor detects the type of file that you are editing, and attempts to show an editing interface that is tailored for that type of file. The most apparent (and at time of writing, the most developed) of these contextually aware editing interfaces is that for Markdown. When editing a Markdown file, the interface will display the source text and a “live preview” side-by-side. It will even attempt to provide keyboard shortcuts and formatting buttons that reflect the editor’s capabilities. However, for more generic files, the editor will display a “plain” editing interface without the live preview.
The editor tries to minimize the amount of scrolling you have to do.
Both the Markdown and generic editors attempt to “synchronize” the editing and preview windows to the best of their ability:
- The generic editor attempts to show the approximately similar scroll distance between both the editing window and the preview window.
- The Markdown interface attempts to always highlight the bounding element which you are editing. For instance: if your editing is in a paragraph, it will highlight that paragraph, if you are editing an item in a list, it will highlight that item in the list. This works for both keyboard navigation as well as mouse clicks within the editing area.
The editor will also “save your place” in the editing window, allowing you to quickly preview a document without having to scroll back to your place.
The editor is aware of the version of the file you were originally acting against, and tries to help accordingly.
With the possibility of multiple users operating on the same Giterary instance, there is the possibility that two users can edit the same file at the same time. This has the potential to cause conflicts, as well as lost work due to one person’s edits overwriting another’s.
If ever the editor detects that the file has changed out from underneath you, it will drop into the cherrypicking interface that displays the differences between your version and that which was committed underneath you.
Working within the Editor
The editor allows you to write whatever textual contents you wish. However, learning a few keyboard and syntactical tricks can help to create sharp, well-structured documents very quickly.
Shortcuts and Formatting
Depending on the type of document you’re editing, the editor might give you a number of “shortcut” buttons at the bottom of the editor. These are similar to the toolbars you might see in other editors, but are tailored for the type of document you’re editing.
Each “shortcut” is a combination of either the Control or Alt keys on a keyboard and another single keypress (pressing control or alt first, and then at the same time another key). This “meta” key will be different depending which operating system you’re accessing Giterary from. This is because some systems have other, critical functionality already mapped to these key combinations (and some critical functionality that you cannot or should not customize). For Giterary, Windows and Linux browsers will rely on the Alt key, while Mac OS X browsers will rely on Control. The shortcut bar will indicate which beginning key you should press (either “Control + …” or “Alt + …” at the bottom of the editor).
Each shortcut button shows two things:
- The letter after Control or Alt you need to press in order to use that shortcut ( Control + B, Control + I ).
- The approximate formatting of the formatting in question (bold, italics, etc.).
Most buttons also have two modes associated with them, which are determined by whether you have highlighted something, or if you just have a normal cursor.
If you have highlighted something, the shortcut buttons will usually attempt to apply the corresponding formatting to the text you have selected. This is useful if you’ve already typed out text and wish to apply formatting at a later time.
If you haven’t highlighted anything and just have a normal cursor, an example of the corresponding formatting will be inserted into your editing window with a section highlighted that you need to edit yourself to complete the formatting. This is useful if you want to make use of formatting, but either don’t want to type the syntax required to do so, or forget how the syntax works.
Hovering your mouse over any of the buttons will show a longer textual description of the formatting referenced.
These shortcuts are optional, just the same as using the editor within the Giterary interface is optional. However, if you intend to become proficient at Markdown syntax, these can be useful in learning the syntax as well as becoming proficient at using it. It is highly recommended you explore these shortcuts, as well as review the Markdown syntax documentation, as it will save you time in the long run.
Wikilinks
Wikilinks are a special syntax that you include in the text of your document that allow you to generate a hyperlink to a different document when your original document is rendered.
For example:
[[ANameOfYourDocument]]
Turns into something like this:
You can also specify “display” text along with your link, like so:
[[ANameOfYourDocument|Click here to view my document]]
Which turns into something like this:
Depending on whether that document exists (that is, is present in the latest and greatest version of your wiki content), the link may be colored differently. This is to show which pages you can expect to see content from when clicking on them, and if you would expect to create new content when clicking on them.
The most editor interfaces have a helper function to quickly generate wikilinks.
Functional Links
In addition to “wiki"—style links, you can use “functional” linking syntax to generate links that perform functions around Giterary. These involve using a known “prefix” based on Giterary functions, and specifying the parameters that would be used within that link. For instance, determining the “diff” between two commits within Giterary might look like this.
[[diff:commit_before=HEAD^,commit_after=HEAD,plain=yes|Changes caused by HEAD commit]]
Would render to…
Many functional links exist, some to provide simple navigational links, but also those to provide macro-type functionality to a page’s display. Some interesting function links include:
blame: Creates a hyperlink to the blame for the given file
[[blame:file=MyFile|Blame for MyFile]]
cherrypick: Creates a hyperlink to be able to cherrypick a file and/or given commits
[[cherrypick:file=MyFile,commit_before=HEAD~~,commit_after=HEAD|Cherrypick between head and two revisions past]]
clear_cache: Creates a hyperlink to be able to clear the cache for a page.
\[[clear_cache:file=MyFile|Clear MyFile's cache]]
diff: Creates a hyperlink to show the diff for a file, between different revisions
[[diff:file=MyFile,commit_before=HEAD~~,commit_after=HEAD|Diff between HEAD and two revisions prior for MyFile]]
history: Creates a hyperlink to show history
[[history:file=MyFile,num=100|Show last 100 edits for MyFile]]
partition: Creates a hyperlink to partition a file.
[[partition:file=MyFile|Partition!]]
move: Creates a hyperlink to move a file
[[move:file=MyFile|Move MyFile]]
revert: Create hyperlink to revert a commit
[[revert:commit=HEAD|Revert the head commit]]
search: Create a hyperlink to perform a search
[[search:terms=something|Search for the term 'something']]
show_commit: Create a hyperlink to show a given commit
\[[show_commit:commit=HEAD|Show the HEAD commit]]
stats: Create a hyperlink to go to the stats for a given document/collection
[[stats:file=MyFiles.collection|Wordcount for all files in MyFiles.collection]]
whatlinkshere: Create a hyperlink to search on “What Links Here”
[[whatlinkshere:file=MyFile|Search for files that link to MyFile]]
todo or todos: Create a hyperlink to TODOs specific to a certain directory.
[[todos:file=MyFile.dir|<span class="todo">TODO</span>s under MyFile]]
tag or tags: Create a hyperlink to search for documents with all of the tags specified,possibly limited to a given subdirectory.
[[tags:file=MyDirectory,tag=scene,tag=dark,tag=stormy|A dark and stormy scenes under MyDirectory]]
table or csv: Render an external file as a CSV/Table.
[[table:file=MyTable.csv|My table]]
Optionally, if you want to render a collection or a list as a table, a specialized tabular output for collections/lists is available.
[[table:file=MyList.list|Specialized, sorted list output]]
list: Render a list (inline, or using an external reference) as an HTML list of document links.
[[list:file=MyDirectory/*|All files under MyDirectory]]
You can also specify an external list/collection rather than using the “file” inline list specifier
[[list:list=MyList.list|All files matching MyList.list]]
You can also limit your matches to documents with certain tags:
[[list:file=MyDirectory/*,tag=scene|All scenes under MyDirectory]]
You can also change the sorting direction of the list:
[[list:file=MyDirectory/*,sort=ascending|Files under MyDirectory, listed in order]] [[list:file=MyDirectory/*,sort=descending|Files under MyDirectory, listed in reverse order]]
You can also specify an “excerpt” length, the number of characters from the matched document that a list will include after every match.
[[list:file=MyDirectory/*,excerpt=100|First 100 characters of all files in MyDirectory]]
You can also change how many “levels” deep a directory will display.
[[list:file=MyDirectory/*,display=basename|Only show file names]] [[list:file=MyDirectory/*,display=-2|Show file name and containing folder (but nothing above)]]
edit: Create a hyperlink to edit a file (and to optionally specify a template)
[[edit:template=MyTemplate,file=MyFileToEdit|Edit a file with a given template]]
jot: Create a hyperlink to a page that has date and time pieces as its path components
[[jot:file=MyJournal|Year,Month,Day of Month dash Day of Week]] [[jot:file=MyJournal,format=%Y,format=%m,format=%d|Year,Month,Day]]
template: Create a small form widget to create a new page with a template
[[template:template=MyTemplate,file=Name/Of/New/File|Creates a form to enter a new file name and edit it with MyTemplate template]]
Additionally, if you do not specify the template, the widget will change to add a drop-down list of all documents tagged with
~template
.[[template:file=Name/Of/New/File|Create new file from list of templates]]
image: Creates a link to an internal image
[[image:file=Path/to/my/image|Image alt-text]]
TODO: assoc
TODO: transclude
Annotations
Annotations in documents are ways to highlight and provide notes to a document without necessarily changing it. This is useful for editing and document feedback, providing additional information for other authors, or being able to refer to other portions of your Giterary repository without disrupting the document’s readability.
Note: Annotations are “hidden” by default, and only appear when you enable decorations. If you are browsing from Giterary, hit the “Decorations” button at top, or hit “d” to enable the examples below.
<annotate>
This text is annotated.
<comment>This text is "annotating" the original text.</comment>
</annotate>
Renders to this:
This text is annotated. This text is “annotating” the original text.
Note that with the above syntax, you need not put the “comment” tags at the end of the “annotate” content, nor are you limited to one comment tag within the annotation.
There is also a simplified syntax for this that allows you to provide minimally disruptive annotation syntax in your content, and specify your annotation text either explicitly next to the annotate or later in the document (allowing for a “reference” section, similar to the Markdown feature of allowing the definition of a URL to be apart from its usage.
{The quick brown fox jumped over the lazy dog.}(This is my note.)
...or...
{The quick brown fox jumped over the lazy dog}[referencetag]
...and elsewhere in the document...
{referencetag}: This is my note.
Would generate the following:
This is some annotated text. This text is annotating …or…
The editor has a helper function to quickly generate annotations. While highlighting a section of text, clicking on the “Annotate Selected Text” hyperlinks will prompt you for your annotation comments.
Annotations are displayed as “collapsed” within the CodeMirror editor. To expand them, either move the keyboard cursor into the collapsed region, or hit the Caret in the CodeMirror gutter at left, corresponding to the line in which the annotation resides. An alternative is to hit ‘Alt-H’.
Dialog Highlighting
Dialog highlighting attempts to show a user the approximate balance between dialog content and non-dialog content in a document.
Dialog content generally follows the format of:
“Something something,” she said.
Which consists of:
- Content with double quotes, and…
- The quoted content ending with a punctuation mark (commas, periods, exclamation point, question mark, ellipsis,etc.), and…
- Not part of a “list” ("Item 1,” “Item 2,” and “Item 3").
Note that these are very generic and unsophisticated dialog detection mechanisms, meant to be useful only in common cases. Some consideration is taken for different quoting characters (UTF-8 left quotes and right quotes), but it can only guess as to the different ways you may write dialog.
Markdown
Markdown syntax is a useful way to write without having to worry about syntax. Markdown is the default syntax when not specifying a file extension as part of its name.
To quote the author:
Markdown is intended to be as easy-to-read and easy-to-write as is feasible.
Readability, however, is emphasized above all else. A Markdown-formatted document should be publishable as-is, as plain text, without looking like it’s been marked up with tags or formatting instructions.
This Help document is written in Markdown format. You can view its contents by selecting Other Options > …Readable Text when displayed in Giterary.
There are many great features to Markdown for document formatting. It is highly recommended you familiarize yourself with its function.
Additional Note: One of Markdown’s features is that it will allow HTML tags to be embedded within it (to provide features that Markdown can’t provide). Giterary supports this “HTML pass-through,” however, only for a limited subset of HTML (for security reasons).
Commit Notes
On every editor there will be a “commit notes” field. This field consists of plain text, without any formatting or special syntaxes. This is because this field is intended to record the reasons or reasoning behind your current modifications. Feel like you’re using the word “bustle” too many times? Put it in the notes. Moving some things around to sound more punchy? Put it in the notes. Did it start snowing while you were writing? Put it in the notes.
Why do this because even if 1 in 10 notes are actually useful, it still means that more than zero notes will be useful to you in the future. Over the course of a project you may have hundreds or thousands of edits. If you ever need to sleuth back through your history, you will want to be able to have your notes indicate what your intentions were at the time, or, whatever valuable information you can think to include that is valuable to display along with the changes. Additionally, if annotations do not suffice, the commit notes can serve as a place for your editor to put their notes to describe their overall intent for a change.
However, if meticulous notekeeping isn’t your style, you can keep your commit notes blank, and Giterary will report on the added or subtracted word count from your previous version. This is sufficient for small, non-critical edits, but are less useful over time if you only ever leave the commit notes field blank.
Preview vs. Commit vs. Commit and Edit
While the commit notes for editing are not mandatory, an immediate preview of your document before committing your changesis. This is for a few reasons:
- You should be reviewing your edits to make sure your changes render correctly (sometimes Markdown syntax is a tricky business).
- There may be in the future elements in the editor that require server-side processing (and therefore, require a “Preview” to be able to see the render properly).
- To make sure the file hasn’t changed out from under you.
You can commit in one of two ways:
- Commit, which commits your modifications and then redirects you back to view the file normally.
- Commit and Edit, which commits your modifications and then places you back in the editor with your editing place saved. This is useful for continuously writing a document, or saving your modifications directly to the repository rather than relying on the drafts.
Drafts
When editing a document, a timer will periodically trigger to determine if you have made significant changes in the editor. If so, it will send a “draft” portion back to the Giterary server, containing the contents and the commit against which the draft was being written.
These drafts can be used to recover writing lost after the disruption of an Internet connection, power failure, or a failure to distinguish “Control-W” from “Control-Q” as a keyboard command.
These commits can be recovered by logging in and visiting the “My Drafts” page, which will list all recent unsaved drafts. Clicking on “edit” for a draft from here will load the editor page with the last known draft contents against the document you were editing.
The Wonderful World of Version Control
git provides powerful tools to allow you to see and manage the changes to your documents over time. Giterary’s functionality only brushes the surface of git’s myriad uses, and this author would highly recommend you explore its features for use in your writing projects and any others where text could benefit from version control.
git in a Nutshell
git is a file versioning database. Its sole lot in life is to look at a directory structure, find similarities and differences, record them for the user, and report on them later.
git stores its data as specially organized files alongside the files you ask it to track. This means that while git is a database, its contents are still files, which can be stored, moved, and copied, just like any other files on your computer. This specially organized git directory structure is normally under a directory called .git. Locations on your computer with these .git directories are called repositories.
Giterary allows you to edit and maintain your git repository from a web interface. However, many git client applications are available to do this, and implement larger portions of git’s functionality. We recommend investigating some of these clients in order to take advantage of git’s more advanced features.
Terms from git
Below are terms from git that Giterary borrows and uses throughout its interface:
commit: A “commit” is a set of changes successfully made and recorded to a git repository. Commits can contain many types of changes, including:
- File modifications (to one or more files)
- File creation (for one or more files)
- File deletion (for one or more files)
- Moving a file (or a directory structure)
- Branch merges (referring to a feature of git called “branching,” where totally different versions of a file structure are stored in the same git repository, and they are combined togther). Note that branching is not currently supported in Giterary.
- Reverting one or more commits by restoring the files modified by the commits to their original states.
log or history: A list of commits stored in the repository, often listed in chronological order.
difference or diff: A feature of git which can compare any two files and programmatically determine similarities and differences, and display them to the users. Often the output of this feature is called a diff as well as the process for generating a diff.
blame: A function of git which calculates for a file, line-by-line, the commit, author, and date/timestamp responsible for a version of that line.
History
Giterary can query your repository’s historical log of changes, listing them by commit in reverse chronological order (latest changes first). The history page (available by clicking “Log” in the top navigational element of the Giterary interface) queries the log and displays the results that match your criteria. By default, it shows all changes for all files and all users.
The history log can be filtered in a few ways to show you more specific information:
- You can click on “My Commits” while logged in to see a list of only commits which you were responsible for. ("Show me only my commits.")
- While viewing a file, you can click on the “Revision History” to see a list of commits involving only your viewed file. This works for all files, as well as files which have been renamed at some point in their turbulent past. ("Show me everything that happened to this file.")
- While browsing history, you can click on either the “hist” link on a given row to see a history of the files included in that commit ("Show me the history of all the things that this change touched.")
You can also use the history/log page to view prior versions of files, as well as calculate diffs and document statistics for a given commit.
To demonstrate, you can view the history of this file..
Reversion
As the git repository stores versions of files, it is not unreasonable to need to revert a version of a file back to a previous version. In Giterary, a feature is available to revert specific commits in the system.
To do so, use the repository history to find the commit which you wish to revert. Select the commit’s unique SHA number (under the commit heading). This will bring up a details page on the commit itself, showing author, notes, and the contents of the changes in the commit. If you are logged in, at the bottom of this display is a “Revert this commit” button, which after confirmation, will revert all changes within the specified commit back to their original states. This does not, however, eliminate the history of the repository afterward, it instead generates a new commit whose contents revert the changes.
Comparing Different Versions, or “Diffs”
As described, a “diff” is a programmatic determination of the similarities and differences between two files, or two directory structures. Diffs are used frequently in software development and configuration management scenarios when file modifications must be performed in an automated fashion.
For Giterary, diffs are valuable because they can show the differences between two versions of a file, demonstrated as either additions and subtractions as a result of the modifications necessary to bring one version of the file in sync with the other version of the file. To make viewing and manipulation of diffs easier, Giterary calculates diffs on a “longest word sequence” basis, saying “I added this sentence to the end of this paragraph” rather than “I added 20 words to the end of this paragraph.” This becomes important when using diffs in conjunction with other features (cherrypicking, specifically).
You can calculate diffs in a few ways:
- When viewing a file, you have the option of selecting Other options > Compare …to previous version or Other options > Compare …to previous version (no formatting). The former version attempts to format the resulting additions and subtractions for a diff in the renderer appropriate for the file’s extension, and the latter formats the diff in plain text. Formatting a diff sometimes helps with readability, but additions and subtractions to formatting elements can cause rendering artifacts, in which case, plain text diffs are more readable.
- When viewing history (and with any of the available history filtering options) you can select specific “before” and “after” versions beneath the “show diff” button, and show the resulting diff calculation by hitting the “show diff” button.
- When viewing history, you can select the “head” hyperlink to compare your selected version to the latest “head” version of a file.
- When viewing history, you can select the “prev” hyperlink to compare that commit’s “parent” commit against the “child” you selected.
To demonstrate, you can view the changes that last occurred to this file.
Cherrypicking
Cherrypicking is the concept of taking the output of a diff (with its “additions” and “subtractions") and choosing to keep or discard any number of modifications. This allows you to “revert” changes to a file but on very specific basis (down to reverting single word changes, if necessary).
While logged in and viewing a document, you can select Options > Cherrypick last change to bring up a similar interface to the plain diff action. By selecting the adds/removes in the text in the left column, you toggle whether you will keep or discard that change, and the display in the right column will reflect your choices. When you are done, you can hit the “Put changes in editor” button to put your newly kept/discarded elements into a text editor for further editing.
Even while not intending to cherrypick, this can still be useful for reviewing changes to a document as it provides a “Next Difference” button, which cycles through the changes in the document in order.
Blame
Blame, despite its negative connotation, is a very useful too for seeing the history of a document. Selecting Options > Show …blame for this file renders a page that assigns a commit number, timestamp, author, and color code for each to go with each line of the file. This helps to determine the relative “age” of a line in a file, as well as who made the change.
To demonstrate, you can see the blame display for this HELP file.
Other Features
Other features that may be useful to you.
RSS Feeds
There is a general RSS feed (Really Simple Syndication) located at:
http://YOUR_HOST_NAME/YOUR_GITERARY_PATH/rss.php
It shows each commit as a single RSS entry.
Templates
Giterary allows for a fairly basic form of “templating,” by allowing one document to be used as the basis for a creation of another. This is useful for quickly creating a number of documents with similar content.
On any document, you can choose from the “Other Options” drop down the “Use this as a template” item. This wil allow you to use the source page as the initial contents of a chosen target page.
If you have a number of templates which require repeated use (or that their use only differs slightly), there is a function link helper available to create a template form on a given page. For instance:
[[template:file=Path/To/File,template=Path/To/Template|Create a new file]]
…will render as the following:
This allows the user to enter in the target for the template’s contents without being forced to navigate to the template each time.
Relative time display
Often it’s less important knowing the date something happened, and more important to know something’s relative age.
For most date displays, and particularly those in space constrained elemented on the Giterary interface, dates and times of events (commits, etc.) are reduced to relative time values. For instance:
- +11min means something happened between 11 and 12 minutes ago (as of last page refresh)
- +2H means something happened between 2 and 3 hours ago.
- +4M means something happened between 4 and 5 months ago.
In most places, if the date isn’t already displayed, a mouseover tooltip is provided to show the actual date used for the relative time.
“Jotting”
While there are numerous ways to use Giterary as a journal, or to quickly find a place to write quick notes, there is one way which was implemented to make such things a little less tedious. The “Jot” navigation hyperlink (presented when logged in) will immediately drop you into the editing interface of a file with a naming convention that is convenient for keeping time-based data. For instance, if the date is January 21st, 2013, hitting “Jot” on this date will drop you into an editor for the file:
myusername/jot/2013/01/21-Mon
These files are useful for recording random thoughts or information without having to worrying about exactly where you want to put it.
You can generate your own “jot” links with the jot functional link syntax. For instance:
[[jot:file=yourusername/jot|My Jot]]
…will generate the same “jot” link as is provided by the navigation “Jot” link. The file
parameter is optional, and can be used to determine the prefix under which the jot file will be targeted. In this case, we want to create our files under yourusername/jot
You can also modify the formats used by the jot function by specifying the format you would like to use for the path elements. For instance, if you wanted to explicitly define the same format as is used in the navigational “Jot” link, you can specify the format like so:
[[jot:file=yourusername/jot,format=%Y,format=%m,format=%d-%a|My Jot]]
For each format
parameter, the jot functional link syntax will generate a new path element.
The “%_” parameters used in the format are those used in PHP’s strftime
function. Any format available to that function will be available as a path element on the jot functional link syntax.
Additionally, with functionality similar to as described for Templates, you can specify a template to be used to pre-populate the contents of your target jot. Specify your template path with the template
parameter like so:
[[jot:file=yourusername/jot,template=My/Journal/Template|Next Journal Entry with Pre-populated Content]]
…which will render like so:
Next Journal Entry with Pre-populated Content
Tags
Tags are ways to categorize and group certain documents. For instance, you might be organizing your chapters and component scenes into their own folders:
MyBook/Chapter01/SupportingDocs/Playlist
MyBook/Chapter01/SupportingDocs/Imagery/Image01.jpg
MyBook/Chapter01/SupportingDocs/Imagery/SceneLayout.jpg
MyBook/Chapter01/01-IntroScene
MyBook/Chapter01/02-SuddenActionSequence
...
MyBook/Chapter02/01-WakeUpInAStrangePlace
MyBook/Chapter02/02-Amnesia
However, you want to find all scenes that contain characters X and Y.
You can perform a search for a character’s name, but that isn’t always ideal (what if your character doesn’t have a name?). You can try to reorganize your folder structures, but this becomes unwieldy, and can cause a lot of extra work if you end up needing to organize again, or organize in multiple ways depending on what you’re looking for.
To address this, Giterary has the concept of “tags,” which are the rough equivalent of “categories” in other wiki software. You can tag a document by entering a “~” (a tilde) at the beginning of a line, followed by a word (no spaces). A document can have as many tags as you like. For example:
Lorum ipsum, etc. Blah, blah
~scene
~character_name
~angry
This makes this document appear when searching for tags “scene,” “character_name,” or “angry.”
You can search for tags by clicking on the “Tags” hyperlink in the navigation bar. This will provide a list of all available tags (which you can then click on to search on documents tagged as such). You can also navigate to a directory view of a particular page, and search for a tag, limiting the scope of the returned tags to that particular directory structure.
Additionally, there is a function link you can use to create automatic tag searches based on specifications you provide. For instance:
[[tags:tag=scene|All Scenes]]
Would render to something like:
Note that you can “combine” tags, such that documents returned by the search have to contain all of the tags you specify (not just one). For instance:
[[tags:tag=authorbias,tag=fireflyreferences|All docs referencing Firefly, with Author Bias]]
…will search for all documents that have both the tag for authorbias and the tag for the fireflyreferences:
All docs referencing Firefly, with Author Bias
Tags can be a powerful mechanism for quickly accessing documents across multiple file structures. They are, however, only useful for documents that are tagged, and tagged consistently. It is advised that some forethought is put into how you may want to tag/categorize your documents in the future, particularly as a project scales in size and complexity.
Some potential uses for tagging include:
- Tagging scenes/chapters with the characters involved
- Showing which documents refer to a particular plot thread, foreshadowing, or later reveal.
- Organizing scenes/chapters by their setting ("The Battle Room,” “At the office")
TODO and TBD searching
Sometimes it is daunting to approach a document or a series of documents all at once. Case in point: Giterary’s help documentation. When writing the documentation you will think of things that need to be written, but aren’t part of your focus at the immediate moment. Switching gears will make you lose your train of thought, but it might slip your mind if you ignore it for too long.
This is where “TODO” patterns are useful. When logged in, you can visit the TODO link next to the “Jot” link in the navigation next to the search bar. This displays all lines in documents that contain either “TODO” or “TBD".
These lines can serve as anchors for later work. You can also use them to describe the basic intent of a section, and then work through your “TODOs” as time allows. As you eliminate the items in your TODO list, you get closer to completing your work.
It should be noted, though, that plain TODO listings will display in the document rendering.
Associations
TODO
Aliases
TODO
FAQ
Frequently Asked Questions
I’m not technical enough to set up Giterary, but I like some of the features, and the price is right. What can I do?
I was once tasked at work with installing up a homebrewed Linux distribution. As part of its install process, a single-user mode prompt would drop me into an install script. That script began with a note from the author that said, “I never promised you a rose garden…” (quoting the 1970 Joe South/Lynn Anderson country song “Rose Garden”) and finished by threatening to smash my hard drive platters if I didn’t understand something. It succeeded at making me both feel incredibly alone and helpless in my task, as well as made me feel like I never wanted to ask the author for help. Which I think was the desired effect.
I made this Giterary thing, and my only good measure of success is getting people to use it, or want to use it. I don’t offer a lot of promises (and I’m a terrible gardener), but I do want to be available to help people set this up as well as get it so that more people can set it up. As I develop this further, I intend to try to make it easier to get Giterary deployed to any operating system, anywhere, with its full features enabled (git repository synchronization, etc.). However, configuration and installation are hard things, even if you have an extremely small list of dependencies.
Right now it’s easiest to install on Linux (as that is what I’ve been developing Giterary on). If you’re installing on Linux, there is a install.sh script will take you through collecting your various bits of configuration information, setting up your directory structures, permissions, usernames, passwords, and other fun things. See the INSTALL documentation referencing the install.sh script for more information. It requires being a little bit tech savvy, and a familiarity with Linux-y types of things, but nothing insurmountable.
(Also, if you’re curious, I did get the “No Rose Garden” Linux installed, and everything turned out easier than expected. And I learned a few things along the way. And so, too, will you, intrepid adventurers!)
Markdown is okay, but I like X better. Do you support that?
Probably? Is it text-based? Is it easy to edit from an HTML textarea tag? Well, there are certainly places to add such things, but there isn’t anything particularly fancy. For the programmers out there, it’s a PHP switch statement, that passes off handling to a function that is assumed to return valid HTML. However, a lot of work goes into making Markdown-specific editing possible (with the addition of annotations, the live Markdown preview, etc.)
Editing with Giterary is pretty lame. Why don’t you use a WYSIWIG editor? Or something I’ve likely used before?
In the same way that text files are hard to screw up, so too is plain text editing. There will always be subtleties and intricacies of every file format, which I will eventually get wrong if I try to account for them all. And not to disparage the writers of WYSIWIG editors, or the users of Giterary, but sometimes it’s nice to have something familiar and simple, even if it is sort of plain.
That said, Giterary will try to help with the editing process. It will attempt to provide syntax coloring using CodeMirror, but you can toggle this off if you so desire. However, in the event of complete Javascript failure (or you run NoScript), your browser should be able to render the textarea just fine, and also be able to preview and commit your changes without need for the client-side Javascript. I’m a fan of elegantly degrading web applications.
You also have the ability to edit outside of the Giterary web interface by using an external text editor, and synchronizing using a Git client. In this case, Giterary can simply be a navigational and organizational tool for your files.
I don’t understand why I would ever use partitioning. Why would I ever want to split up my document?
Valid question. It’s more of a feature for people who, prior to writing in Giterary, or prior to sane document management practices, worked only in single, monolithic documents (see: one great big Word document, or something like that). A feature like that is useful because it lets you split up a larger work into smaller, more manageable chunks.
Something broke, and my repository is messed up. Giterary isn’t helping at all. I don’t want to start over. Please help.
More often than not, an external git client, graphical or otherwise, will be able to answer your git repository’s quandary better. At very worst, copying your working directory out, and cloning from your last known good repository state should be sufficient to not lose what is in your working directory.
I put something in my repository that is, um, “sensitive.” As in, it needs to be gone. Really gone.
It happens sometimes. Usually, performing a “hard reset” to a commit before the sensitive information was in the system is sufficient.
git reset --HARD COMMIT_BEFORE_BAD_STUFF_HAPPENED
But sometimes there are things you want to keep that happened after the sensitive information got into the system. In that case, you have to use git to “rewrite history.” For this, Github has a decent article on how to do just this.
Is Giterary supported on X (X being my operating system or computing platform of choice)?
PHP, being an interpreted language, does not require compilation, and therefore, is supported on any platform a PHP interpreter is available (version 5.3). However, you also need git to be able to run git, and a web server capable of serving PHP scripts, and your operating system needs to support the type of piping used by the proc_open function in PHP. But other than that, pretty platform agnostic, I’d think.
I have a healthy degree of paranoia, does Giterary support file encryption?
Not at the moment, but it’s an interesting and precarious feature. For instance: you could implement it such that you would have to enter an extra password in order to “unlock” a file for editing. However, unless said paranoid individual isn’t also paranoid about their network traffic, it’s possible that the submission of that password could be intercepted.
So: it’s possible. An extra extension handler, plus perhaps a modified form element, and you’d be in business. But it certainly wouldn’t be perfect, and would play hell with Giterary’s diff mechanisms.
What coding conventions were used in the application, if any, you talentless hack?
You can read about some of the programming conventions, if you really want, but it’s mostly the technical grandstanding and pseudo-philosophical ravings of a madman.
What license is Giterary released under?
Giterary is licensed under the GNU Public License, version 3. License text is (should be) included in your distribution of Giterary.
There already exist industry standard word processing and novel writing tools, cheaply available, reliable, and better documented than this. Giterary is destined to fail.
Wow. No punches pulled. Also, I didn’t see a questionmark. But alright, let’s dance.
Consider shovels: levered surfaces with varying shapes and sizes. Flat-headed shovels are good for loose material, pointed shovels are good for digging into soil or cutting through grass/sod. Snowshovels are specialized and great for moving snow, but not much else. You could even say that a post-hole digger (
which digs holes for posts ) is a type of shovel for removing soil in a small, deep, cylindrical area (but probably not good for much else).Obligatory Firefly reference, please forgive me. The point is: nobody in the shovel industry, or any person whose profession requires moving soil, rocks, snow, or digging posts, will say that an industry standard exists against which no other shovel can compete.
However, the way people use computer software is weird, in a fashion that the way people use shovels is not. People agree to use products like Word, or Excel, or PowerPoint, or Outlook, or Scrivener, or Photoshop, or Premiere, or AutoCad, or Windows, or iOS, etc., because they are marketed with the notion of trust and support. Perception of trust in software far outweighs any set of features, performance, or cost, as if people trust something, they’ll pay anything for it. You may pay extra for a metal blade on a shovel or a nicer grip, but you’ll never buy a shovel because you trust it the way you would Photoshop.
Trust sells, because people don’t inherently trust their ability to use computers. And software companies know this, and design and market their software such that that trust is maintained. Companies hold on to proprietary file formats for as long as their industry can tolerate it. Schools are sold discount copies of hardware and software so that teachers will teach their product, and children grow up thinking that a certain product is accepted or necessary for a computing task. Universities sell student copies of software cheaply to ensure career-bound students are most familiar with a given application, and are taught that they are the industry standard tools.
That said, software is hard to make. Good software even harder. Millions of man-years have gone into the various versions of industry-accepted applications, and as such, they tend to be better products. But software should be treated as tools, not as emotional attachments, and should be evaluated on their effectiveness.
Giterary tries to fill a niche I think is poorly addressed, or poorly architected in other tools. It is simply a mashup of already established software, freely available on the web, but I chose that software because it did its job, it did it right, and did it in exactly the way I wanted. Settling for a tool just because “everyone else uses it” is silly. It should be the right tool for the job, based on features, time saved, learning curve, and price point.
Additionally, Giterary is unique in that it encourages users to put their work into files and formats that are not beholden to any software license or encoding scheme. Giterary wants you to use other, better tools, and let Giterary handle the stuff that those tools don’t. It seems silly to argue against the doom of software obscurity by saying that I make it easier to walk away from Giterary, but that’s not really the feature that brings users back. It’s that you are allowed to choose, where otherwise you are not.
My hope is that as people become more computer literate, and less tolerant of their “industry standard” tools, they’ll realize that sometimes a post-hole digger isn’t the best for moving snow.
/soapbox
Does Giterary support X method of authentication? Y method of authorization? How can I give person A permissions to do this, but not person B? Can I shout the words “Active Directory” three times and be able to log in successfully?
There is only so much I can do to predict what people will use Giterary for, or who the will want to be able to use Giterary. If you or your organization require complex rules to determine who can do what and where and when in Giterary, you might be looking for a Content Management System (such as Wordpress, Drupal, etc.), which solves this problem much more elegantly.
That said, Giterary’s barrier to entry on creating new but only slightly different things for authentication and authorization is pretty low. If you can easily solve a problem with a single PHP class, then it’s pretty easy to wire up. It is also fashioned such that you can easily have multiple “registered” things that can tell you if you’re allowed/not allowed to do something, keeping from making your dependence on one and only one “thing” to answer all questions. It asks all of its registered things if you can do something until either if runs out of things, or gets an “affirmative” answer.
What the heck is this gibberish you turned my passwords into? And why, uhm… why does it still work?
These are password “hashes,” or, algorithmically generated values that are hard to guess their original value. These enable Giterary to answer “Does this person have the right password?” without ever having to store their password. Giterary does this by taking the same hashing algorithm as was used in your password, and performing the hashing on your submitted login password. If the resulting hash matches the stored hash, the passwords match, and you can successfully log in.
The install documentation has an in-depth description of these, how to generate them, and how to enter them into your passfile.csv.
authorbias
fireflyreferences
AUTHOR
Giterary’s author is Josh Rhoades, a programmer, from Alaska. He believes in better living through computer science principals and Penny Arcade comics. He uses Vim, SSH, git, and an aging Macbook Pro.
Giterary began atop a mountain, when someone said “We should write a book.” Despite investigating many alternatives, no software solution solved this particular problem in a way that made sense. And thus a project was born.
The bulk of Giterary was created in the span of about 6 months, starting summer 2012. It was inspired initially by the Wigit codebase for its minimal solution and its few required dependencies.
If you’re interested, an article exists for Giterary on its programming decisions and conventions, plus licensing information, if that interests you.
Thanks go to:
- Mike Rutledge, beta tester
- Katy Laurance, beta reader
- My parents, for asking good questions
- John Gruber and the contributors to Markdown
- Michael Fortin and the contributors to PHP Markdown
- John Fraser and the maintainers at Showdown
- Christian Bach and the contributors at Tablesorter
- Remko Tronçon for his work on Wigit
- Whoever added the “—-follow” tag to git log
And everyone who had to listen to me go on about this, and were disappointed that I wasn’t actually writing a book. (yet)
authorbias
CONVENTIONS
Programming Conventions
Description of file structures, naming conventions, and coding conventions used through the Giterary codebase.
Sure, it’s MVC… ish.
I suppose, technically, Giteary’s codebase follows an MVC-type architecture. That is, if you say that:
- git is the “model”
- “views” are the render and layout templating mechanism
- “controllers” are a series of functions to route requests based on user parameters
That said, it’s certainly not pretty, and violates quite a few things that other codebases implement much better. I try my best to separate display logic from data logic, but honestly, PHP itself is sort of a templating language that got out of hand.
File Structure
/*.php Files for accepting parameters, routing to functions,
and providing the right bootstrapping "require"
statements to handle requests.
/css/ CSS
/js/ Javascript
/include/*.php Function definitions, named according to their site function.
/include/config.php Configuration bootstrapping
/include/util.php Utility methods used application-wide
/include/git.php Functions for interacting directly with git
/include/git_html.php Functions for translating git output to HTML
/include/display.php Functions for rendering and translating documents from Markdown, CSV,
text, or any other formats.
/include/config/*.php Configuration PHP and config "libraries"
/theme/ Storage for "theme" renderables for the templating mechanism
/theme/default/ Storage for default theme
/theme/*/renderable/ Storage for "renderable" PHP pages for the templating mechanism
/theme/*/renderable/layout Storage for "renderable" PHP pages for the templating mechanism
Function naming
git_* functions
Functions that interact directly with git. Usually the suffix will correspond directly to the git “verb” being used.
gen_* functions
Functions that “generate” HTML output, but also have the possibility to serve as “shim” functions to separate functionality like “Am I allowed to perform this function?” from the actual execution of the function.
Additionally, serves to provide a “staging area” for handling default variables or configured variables before passing off to the “executing” functions.
_gen_* functions
Functions prefixed with _gen tend to be the “executing” functions, counterparts to their parameterizing and authenticating gen functions. These tend to have more or less options than their gen counterparts, being the “advanced” interface to a particular feature, or being a function that serves more than one set of gen functional areas.
Keep Things Simple Where They Should Be Simple
If at all possible, it is recommended that you keep “logic” code out of the root *.php files, instead delegating display logic to underlying functions. For instance, the PHP file to display search.php is
require_once( dirname( __FILE__ ) . '/include/header.php');
require_once( dirname( __FILE__ ) . '/include/footer.php');
require_once( dirname( __FILE__ ) . '/include/util.php');
require_once( dirname( __FILE__ ) . '/include/git_html.php');
require_once( dirname( __FILE__ ) . '/include/edit.php');
$term = substr( $_GET['term'], 0, 100 );
echo layout(
array(
'header' => gen_header( "Search" ),
'content' => gen_search( $term )
)
);
Its only concern is accepting the request, search terms, and passing them to the gen_search() function. It does not call any of the git_ functions, instead relying on the gen_ HTML generation to indicate display, success, or errors.
Architectural Concerns
Why don’t you use library X to do Y? Wouldn’t that be easier?
Or: Why did you build your own templating system, git interface, user permissions, and user auth systems?
At least I used git, doesn’t that count? :)
It’s hard to strike a good distance between a piece of code doing exactly what you want and the amount of work it takes to get you there. Some problems are better left to those with doctorates in computer science or mathematics, or those that get paid handsomely to solve such problems for their employers and contribute their efforts back to the open source community.
That being said, it’s rare that I find a programming library that solves a particular set of problems in ways that:
- Fit with my level of paranoia
- Fit with my level of vague technological elitism
- “Get out of my way” if I want to do something that might be considered unwise.
I don’t pretend to be a great programmer, and I’m usually willing to defer to the expertise of others. However, sometimes you have to do bad things © for good reasons. Using libraries built on the design decisions of others means that eventually your requirements draw outside the lines of the intended use of a library. I appreciate the risks. But I don’t like to be constrained by them.
Also, package management. There are great systems out there that manage packages and their dependencies. I like to build things that are simple enough that they don’t require package management, or, can exist without the need for package management.
LICENSE
License
Author’s interpretation of the GNU Public License
The GNU Public License is a general license for the distribution of free software ("free” as in “freedom,” not “free” as in “beer"). You can receive, modify, and distribute Giterary’s codebase under the GPL, which is to say, in a very open fashion. However, as you received it under this license, I am not held accountable for anything that happens as a result of your use of it. I also disclaim and have no legal rights to things you create with Giterary. Make great things, you owe me nothing.
I made this to help people write and organize their stuff, but I provide no guarantees. If you’re going to write something important, I can’t stress enough the importance of figuring out how to ensure that your writing or your work is never lost. Giterary attempts to make this process easy by only ever dealing with files, directories, and tools trusted by hundreds of thousands of other developers, and licensing it such that other developers can potentially make it a better product, but that doesn’t stop hard drive failure or theft.
I would ask that you don’t use my name or the name Giterary for commercial gain without my permission, but the GPL license does not forbid you to do so. Plus, I don’t have a high degree of confidence that I’m the only person to ever use the name Giterary.
If you have licensing questions on the use of Giterary I am happy to field them. Not that I’m particularly well-versed in the legal quagmire that is intellectual property law, but you know, I’ll try to help.
- Josh Rhoades