* Directory layout Here's the gist: - ~/config.yaml~ : Top-level website configuration - ~/Makefile~ : duh - ~/git-setup~ : set up git hooks (see below) - ~/src/~ : website content - ~/out/~ : where the generated output goes - ~/bin/~ : programs you usually won't need to invoke directly - ~/lib/~ : the body of site generator (see also: ~/bin/sitegen~) - ~/doc/~ : additional documentation The web server should serve the union of ~/src/~ and ~/out/~. On the ~master~ branch, ~/out/~ is ignored. But ~git-setup~ will set up a git post-commit hook to generate ~/out/~ and commit it to the ~pre-generated~ branch. More completely, ~git-setup~ sets up ~/bin/post-commit.githook~ as the git post-commit hook; which does two things: - run ~bin/auto-changelog~ (desribed in "ChangeLog", below) - run ~bin/pre-generate~ (described immediately above) * Make targets The Makefile provides several .PHONY targets of interest. - ~all~ (default) : Generate all generated files. While the main site is all generated by ~/bin/sitegen~ (which is called by the Makefile), other generated assets (CSS) is generated by the Makefile directly. - ~serve~ : Alias for ~serve-8000~ - ~serve-PORTNUMBER~ : Run an HTTP server on PORTNUMBER. Search won't work, and file names are case-sensitive. * Make dependencies As mentioned above, the generated static output is committed automatically to the ~pre-generated~ branch (assuming you've run ~git-setup~; so the server does't actually need all of the sitegen dependencies. However, the computer being used to commit does. Those dependencies are: - ~all~ - GNU Make - GNU wget - Ruby - Pandoc 1.17+ - Poppler - scss - ~serve-%~ (in addition to what is needed for ~all~) - unionfs - python3 * Authoring pages If you drop a file in the ~src/~ folder, the site generator will try to turn it into usable HTML. The big caveat is that files *MUST* to be in all lower case (this is to efficiently handle the requirement that URLs be case-insensitive)! Currently supported formats are: - Markdown (~.md~) : converted with Pandoc - Org-mode (~.org~) : converted with Pandoc - PDF (~.pdf~) : embedded with PDF.js I don't need to tell you how to make these types of files. In addition to the raw content of the files, you'll want/need to set metadata about the page. Each of these format supports embedding metadata in the document. ** Setting metadata: Markdown Metadata for Markdown files can be set by adding a block of YAML at the beginning of the document, terminated with "---". This isn't "standard" markdown, but is a common syntax extension (Pandoc calls it ~yaml_metadata_block~). #+BEGIN_SRC --- key: value key2: - any YAML values --- ...rest of document... #+END_SRC Pandoc may make use of some of these metadata attributes internally when converting to HTML. See the Pandoc documentation. ** Setting metadata: Org-mode Metadata for Org-mode files can be set by adding ~#+KEY: value~ lines at the beginning of the document. #+BEGIN_SRC #+KEY: value ...rest of document... #+END_SRC Pandoc may make use of some of these metadata attributes internally when converting to HTML. See the Org-mode and Pandoc documentation. AFAIK, unfortunately Org-mode only has values as strings, no structured data. ** Setting metadata: PDF PDF files natively support embedding certain bits of metadata. The bits that we use are: - title - author - creation date - modification date If you need to set any other metadata attributes, or want to override the values in the PDF (since setting them can be difficult), create YAML file with the same name as the PDF file, but with the ~.yaml~ file extension instead of ~.pdf~. ** Metadata attributes that are handles specially There are some metadata attributes that are used specially by the site generator: | attribute | default value | standard | format | |------------------+---------------------------------+----------+-------------------------------------------------| | title | the first line of the file | Pandoc | string | | author | ~config.yaml:default_author~ | Pandoc | string +or list+ [fn:1] | | license | ~config.yaml:default_license~ | no | string | | pandoc_flags | "" | no | string ("--foo --bar") | | pandoc_format | either "markdown" or "org" | no | string ("markdown+extnsn1+extnsns2") | | html_head_extra | "" | Org-mode | string | | class | "" | no | string (CSS class to apply to ~~) | | categories[fn:2] | "" | no | string ("ES HB") or list (["ES", "HB"]) | | published[fn:2] | first git commit for file | no | string (Ruby ~DateTime::parse()~) or date[fn:3] | | updated[fn:2] | most recent git commit for file | no | string (Ruby ~DateTime::parse()~) or date[fn:3] | [fn:1] We don't support lists of authors, though the Pandoc "standard" does. [fn:2] The "published"/"updated"/"categories" terminology is borrowed from the Atom specification (RFC 4287), and I intend them to have the same semantics. For "published"/"updated", the Pandoc "standard" variable name is "date"; but I thought that was dreadfully ambiguous and confusing when the site generator deals with two distinct dates. [fn:3] At various times there have been bugs in the YAML parser library that Pandoc uses, causing it to fail to parse dates, so I just always put the date in quotes now, and let Ruby ~DateTime::parse()~ take care of it. * Customizing index pages The generated index pages (directory listings) may be influenced by an ~index.yaml~ file placed in the ~/src/~ directory they describe. There are only 3 attributes that we look for in the ~index.yaml~ files: | attribute | default | format | |-----------+------------------------------+-------------------------| | title | File::basename(dirpath) | string | | author | ~config.yaml:default_author~ | string | | external | empty list | list of maps; see below | * Adding pages hosted elsewhere In the directory you wish for the externally hosted pages to appear in, add the metadata to the page to external list. For example, adding "365 Tomorrows: A Simple Lament" to the "writing" directory: #+BEGIN_SRC title: "Writing" external: - title: "365 Tomorrows: A Simple Lament" url: "http://365tomorrows.com/12/03/a-simple-lament/" published: "2013-12-03" categories: [FF] #+END_SRC The metadata attributes for the external pages are very similar to the attributes for local pages, but with fewer defaults: | attribute | default | format | |------------+------------------------------+--------------------------------------------------| | url | mandatory | string | | title | mandatory | string | | author | ~config.yaml:default_author~ | string | | categories | "" | string ("ES HB") or list (["ES", "HB"]) | | published | value of ~updated~ [fn:4] | string (Ruby ~DateTime::parse()~) or date[fn:3] | | updated | value of ~published~ [fn:4] | string (Ruby ~DateTime::parse()~) or date[fn:3] | [fn:4] It is mandatory to set at least one of ~published~ or ~updated~. These externally hosted pages also show up in the Atom (RSS) feed. * The ChangeLog Whenever a you commit, post-commit hook runs ~bin/auto-changelog~, which will only continue to run if the commit touches a ~.org~ or ~.md~ file to the ~/src/~ directory (with the special case that it ignores files named ~index.md~ or ~changelog.md~). If the commit does add or change such a file, then it uses the git log to prepend an entry to ~/src/changelog.md~, and commits that. The format that it uses is loosely based on the GNU Coding Standards' recomendation for ~ChangeLog~ files. If you want to update the changelog manually, or edit an entry, feel free. But be warned that the first 3 lines of the file are reset every time ~auto-changelog~ runs.