Summary Files Commits Branches @commit @diff @stats
path: root / README.md
blob: 1791830eab02f1641f7de5367d7b08dff8b708a3 (plain) (blame)
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
# csg

csg is the "complicated (static) site generator".
It's a somewhat simple static site generator, written in a shell script, with many "poweruser" features thanks to [awk](TODO).
The shell script and underlying awk scripts are POSIX compatible.

The overall design is heavily inspired by [Roman Zolotarev](https://romanzolotarev.com/)'s [ssg](https://romanzolotarev.com/ssg.html), however the codebase is completely different, with the added bonus of:

- arbitrary file modifications via awk
- git-based "created" and "edited" timestamps
- support for (multiple) description and title meta tags
- support for custom title format

## How to use (for the layman)

Inside a "source" folder you put your content, structured in any way.
Your webpages are written in Markdown and must end with `.md`.
You'll also need to have a `_header.html` and `_footer.html`, both of those will be slapped on the top and bottom of your Markdown pages.
Then run:

```bash
csg './source' './destination' '& - You' 'https://you.com'
```

- './source' is your source folder
- './destination' is where you want your generated website to go
- '& - You' is the format of your title, `&` takes the first `h1` from the page and puts it in, with `\\&` you can put an actual ampersand
- 'https://you.com' is your website

If you want to use awk scripts for extended functionality, put them in a folder and reference it at the end of the command:

```bash
csg './source' './destination' '& - You' 'https://you.com' './awk-scripts'
```

### Demo

This repository comes with a small demo setup.
To test it out, run:

```bash
./csg ./demo/src ./demo/website '& - Demo' ./demo/awk-edits
```

You will find your website, ready to be served, inside `./demo/website`.

## Regarding awk

Additional features are available with [awk](TODO).
By default, the title, description, word count, date created and date edited are taken from every Markdown file.
The title and description will be put in place of `[TITLE]` and `[DESCRIPTION]` inside `_header.html`.
You can also create/use your own awk scripts for further page modification (all variables will also be available inside those scripts).

### Writing your own scripts

There are some things you must consider while creating an awk script:

1. It will be ran on the generated HTML pages
2. It's name **must** start with a capital letter
   - You can also create so-called "libraries", mainly awk scripts with only function definitions
   - libraries **must** start with a `#` character in their name, and are included with every script
3. The current line **mustn't** be printed (unless you want to add a line to the file)
   - With awk we can modify only certain lines, but the easiest way to get the whole file with the modified lines, is to just print every line.
     Such a rule is "appended" to the end of your script.
   - Do modifications to `$0` instead of `print (fancy expression)`
   - If you don't want to print a line, do `$0 = 0`
4. Every script **must** begin with a `# regex` line
   - For optimisation purposes, a script is ran only on the files which match the given regular expression
   - The regex is on the whole path, so you could make changes (for example) to specific pages or all pages inside folders
   - The regular expression is fed to `find -regex`, so for exact support view `find`'s documentation
5. Script variables **mustn't** collide and you **mustn't** use `exit` or `nextfile`
   - Also for optimisation purposes, scripts with the same regex are combined into one
6. Inside your scripts you'll have the `title`, `description`, `words`, `created` and `edited` variables available
   The last two will be dates in the format "%d %B %Y", and are only available if your website uses git.

## Usage of the script

csg comes with a help message, which contains everything you might want to know for running the script:

```
Usage: csg [-h | -? | --help]
       csg <source_dir> <destination_dir> <title_format> <base_url> [<scripts_dir>]

Options:
  -h, -?, --help    Print this help message (also available when given no
                    arguments)

Arguments:
  <source_dir>         Folder which contains source files
  <destination_dir>    Folder in which the generated site will be put
  <title_format>       Format string for page title
                       Accepts any text or HTML, & is replaced with contents
                       title (first h1 header).
  <base_url>           Base URL of your website (scheme + authority), without
                       trailing "/", used for sitemap generation.
                       Example: https://google.com
  <scripts_dir>        Optional, folder which contains awk script for editing of
                       generated webpages.

Variables (you can predefine):
  CSG_TIMESTAMP_FILE    File path for git-based timestamps (when git exists)
                        Default: "./timestamps.txt"
                        Disable: ""
  CSG_TMP_DIR           Directory to put temporary files
                        Default: "/tmp"
  CSG_AWK               awk executable and flags
                        Default: searches for gawk
  CSG_MD_TO_HTML        Program to convert Markdown to HTML and it'\''s flags
                        Default: searches for lowdown

Dependencies (required):
  bash, printf, find, cpio


csg - complicated (static) site generator
Created by Syndamia, https://gitlab.com/Syndamia/csg
```

## Future features

1. The way awk scripts are integrated and ordered is somewhat messy and needs major rethinking.
   Ideally you should be able to run an awk script on the markdown, on the markdown generated html (as is already done) and on all final HTML pages (so you could create a list of latest articles with certain excerpts from them, for example).
   There is also the need to be able to reorder script execution easily, without script modifications (so when using someone else's script, you dont need to change it, hence you can include it with a git submodule or sync it with rsync).
   - The regex on top of awk scrits is for optimization purposes, but maybe this new system should be able to figure out when a script needs to be ran?
2. Right now the whole website is regenerated every time, it's important to add a system for updating only the currently changed pages.
   I'm not entirely sure how to do that, since we remove the source Markdown after it is converted to HTML, current thinking leads me to a file containing lines of "filepath hash", but we'll see.
3. Timestamps.txt but based on created/edited file stats
4. Need to add a `_ignore` file to not convert certain folders
5. Add native support for more awk parsers and markdown to html converters