summaryrefslogtreecommitdiff
path: root/README.org
blob: e95aff550e5318b6d0ee7608f3627e32751bc4dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
* 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
   - Ruby
   - Pandoc 1.17+
   - 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 ~<body>~)         |
| 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.