├── VERSION ├── docs ├── layouts │ ├── post.html │ ├── tag.html │ ├── tags.html │ ├── page.html │ ├── blog.html │ ├── page-toc.html │ └── default.html ├── .gitignore ├── assets │ ├── favicon.ico │ └── README.md ├── content │ ├── opt │ │ ├── h.txt │ │ ├── V.txt │ │ ├── p.txt │ │ ├── d.txt │ │ ├── 4.txt │ │ ├── D.txt │ │ ├── e.txt │ │ ├── i.txt │ │ ├── C.txt │ │ ├── t.txt │ │ ├── H.txt │ │ ├── S.txt │ │ ├── r.txt │ │ ├── w.txt │ │ ├── m.txt │ │ ├── I.txt │ │ ├── P.txt │ │ ├── L.txt │ │ ├── M.txt │ │ ├── j.txt │ │ └── T.txt │ ├── blog │ │ ├── index.md │ │ └── 2017-04-13-hello.md │ ├── 404.md │ ├── LINKS.txt │ ├── macros.m │ ├── EXAMPLE.txt │ ├── FLOW.txt │ ├── jqt.1.text │ ├── sake.1.text │ ├── index.md │ └── engine.md ├── blocks │ ├── content │ │ ├── markup.html │ │ └── style.css │ ├── license │ │ ├── markup.html │ │ └── style.css │ ├── body │ │ ├── markup.html │ │ ├── _toc │ │ │ └── markup.html │ │ └── _blog │ │ │ ├── style.css │ │ │ └── markup.html │ ├── container │ │ └── style.css │ ├── logo │ │ ├── markup.html │ │ └── style.css │ ├── toc │ │ ├── markup.html │ │ └── style.css │ ├── filters.jq │ ├── footer │ │ ├── markup.html │ │ └── style.css │ ├── header │ │ ├── markup.html │ │ └── style.css │ ├── menu-bar │ │ ├── markup.html │ │ └── style.css │ ├── panel │ │ └── style.css │ └── repository │ │ ├── markup.html │ │ └── style.css ├── data │ └── snippets.md ├── styles │ ├── media.css │ ├── main.css │ └── milligram.css ├── config.yaml ├── Sakefile └── README.md ├── tests ├── expand │ ├── mpmd-02.md │ ├── mpjqt-01.jqt │ ├── mpmd-03.md │ ├── mpjqt-02.jqt │ ├── mpjqt-03.jqt │ ├── mpmd-04.md │ ├── expected │ │ ├── mpmd-01.md │ │ ├── mpmd-02.md │ │ ├── mpmd-04.md │ │ ├── mpmd-05.md │ │ ├── mpjqt-00.jqt │ │ ├── mpjqt-01.jqt │ │ ├── mpjqt-03.jqt │ │ ├── mpjqt-04.jqt │ │ ├── mpmd-03.md │ │ ├── mpjqt-02.jqt │ │ ├── mpjqt-12.jqt │ │ ├── mpjson-11.json │ │ ├── mpmd-13.md │ │ ├── mpmd-14.md │ │ ├── mpmd-15.md │ │ ├── mpjson-10.json │ │ ├── mpcss-01.css │ │ ├── mpjqt-08.jqt │ │ ├── mpmd-09.md │ │ ├── mpcss-06.css │ │ ├── mpjson-12.json │ │ ├── mpjqt-09.jqt │ │ ├── mpjqt-10.jqt │ │ ├── mpjqt-11.jqt │ │ ├── mpjson-08.json │ │ ├── mpmd-10.md │ │ ├── mpmd-11.md │ │ ├── mpmd-12.md │ │ ├── mpcss-02.css │ │ ├── mpjqt-06.jqt │ │ ├── mpmd-07.md │ │ ├── mpjson-09.json │ │ ├── mpjqt-05.jqt │ │ ├── mpmd-06.md │ │ ├── mpcss-07.css │ │ ├── mpcss-04.css │ │ ├── mpcss-05.css │ │ ├── mpjson-03.json │ │ ├── mpjson-04.json │ │ ├── mpcss-08.css │ │ ├── mpcss-03.css │ │ ├── mpjson-01.json │ │ ├── mpjson-05.json │ │ ├── mpjson-02.json │ │ ├── mpjson-07.json │ │ └── mpjson-06.json │ ├── mpjqt-00.jqt │ ├── mpmd-01.md │ ├── generated │ │ └── .gitignore │ ├── mpjqt-11.jqt │ ├── mpmd-12.md │ ├── mpjqt-04.jqt │ ├── mpmd-05.md │ ├── mpjqt-10.jqt │ ├── mpmd-11.md │ ├── mpmd-13.md │ ├── mpmd-15.md │ ├── mpjqt-12.jqt │ ├── mpmd-10.md │ ├── mpjqt-09.jqt │ ├── mpmd-14.md │ ├── mpjqt-05.jqt │ ├── mpjson-11.json │ ├── mpjson-10.json │ ├── mpmd-06.md │ ├── mpcss-01.css │ ├── mpcss-06.css │ ├── mpcss-07.css │ ├── mpjson-08.json │ ├── mpjson-12.json │ ├── mpcss-02.css │ ├── mpcss-04.css │ ├── mpjqt-08.jqt │ ├── mpmd-09.md │ ├── mpjson-09.json │ ├── mpcss-05.css │ ├── mpjson-03.json │ ├── mpjson-04.json │ ├── mpcss-03.css │ ├── mpjson-01.json │ ├── mpcss-08.css │ ├── mpjqt-06.jqt │ ├── mpmd-07.md │ ├── mpjson-05.json │ ├── mpjson-02.json │ ├── mpjson-06.json │ └── mpjson-07.json ├── jqt │ ├── md-00.md │ ├── loop-52.json │ ├── loop-53.json │ ├── expr-02.json │ ├── expr-01.jqt │ ├── expr-01.json │ ├── expr-51.json │ ├── generated │ │ └── .gitignore │ ├── cond-01.json │ ├── cond-51.json │ ├── expr-51.jqt │ ├── expected │ │ ├── loop-53.txt │ │ ├── cond-02.txt │ │ ├── cond-03.txt │ │ ├── expr-01.txt │ │ ├── expr-51.txt │ │ ├── cond-01.txt │ │ ├── cond-51.txt │ │ ├── loop-52.txt │ │ ├── loop-01.txt │ │ ├── loop-51.txt │ │ ├── loop-00.txt │ │ ├── expr-03.txt │ │ ├── expr-02.txt │ │ ├── expr-52.txt │ │ ├── cond-00.txt │ │ ├── macros-00.txt │ │ ├── bloc-00.txt │ │ ├── syntax-00.txt │ │ └── expr-00.txt │ ├── loop-01.json │ ├── loop-53.jqt │ ├── loop-01.jqt │ ├── loop-51.json │ ├── cond-03.jqt │ ├── loop-51.jqt │ ├── cond-02.jqt │ ├── loop-52.jqt │ ├── expr-03.jqt │ ├── expr-52.json │ ├── md-01.md │ ├── cond-01.jqt │ ├── loop-00.jqt │ ├── expr-03.json │ ├── macros-00.jqt │ ├── cond-51.jqt │ ├── expr-52.jqt │ ├── cond-00.json │ ├── expr-00.json │ ├── loop-00.json │ ├── expr-02.jqt │ ├── filters │ │ └── filters.jq │ ├── cond-00.jqt │ ├── syntax-00.jqt │ └── expr-00.jqt └── format │ ├── yaml-04.sh │ ├── csv-04.sh │ ├── data │ ├── person.yaml │ ├── person.json │ ├── store.yaml │ ├── store.json │ ├── au.csv │ └── au.json │ ├── csv-03.sh │ ├── yaml-03.sh │ ├── yaml-05.sh │ ├── yaml-02.sh │ ├── csv-01.sh │ └── yaml-01.sh ├── .gitignore ├── share ├── lib.jqt.m ├── lib.md.m ├── vimeo.m ├── youtube.m ├── milligram │ ├── image.css │ ├── divider.css │ ├── link.css │ ├── blockquote.css │ ├── list.css │ ├── utility.css │ ├── code.css │ ├── color.css │ ├── spacing.css │ ├── base.css │ ├── table.css │ ├── BEM.m │ ├── typography.css │ ├── form.css │ ├── button.css │ ├── grid.css │ └── COLORNAMES.m ├── slideshare.m ├── lib.css.m ├── lib.json.m ├── sake.d │ ├── phase1.jq │ ├── styles.make │ ├── sitemap.make │ ├── phase3_json.jq │ ├── phase1_site.jq │ ├── sitemap.jq │ ├── tools.make │ ├── phase3d.jq │ ├── phase1.make │ ├── phase3.jq │ ├── configuration.make │ ├── phase2_page.jq │ ├── phase2.jq │ ├── phase3.make │ └── phase2.make ├── lib-common.m └── analytics.m ├── TODO.md ├── bin ├── json2csv ├── csv2json ├── yaml2json ├── yaml2csv ├── csv2yaml ├── json2yaml ├── cq ├── yq └── sake ├── LICENSE ├── bump-version.sh ├── CHANGES └── README.md /VERSION: -------------------------------------------------------------------------------- 1 | 0.5.1 -------------------------------------------------------------------------------- /docs/layouts/post.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/layouts/tag.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/layouts/tags.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/expand/mpmd-02.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/expand/mpjqt-01.jqt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/expand/mpmd-03.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/expand/mpjqt-02.jqt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/expand/mpjqt-03.jqt: -------------------------------------------------------------------------------- 1 | & 2 | -------------------------------------------------------------------------------- /tests/expand/mpmd-04.md: -------------------------------------------------------------------------------- 1 | & 2 | -------------------------------------------------------------------------------- /tests/jqt/md-00.md: -------------------------------------------------------------------------------- 1 | <#empty#> 2 | -------------------------------------------------------------------------------- /tests/expand/expected/mpmd-01.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/expand/expected/mpmd-02.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/expand/expected/mpmd-04.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/expand/expected/mpmd-05.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/jqt/loop-52.json: -------------------------------------------------------------------------------- 1 | { "n": 4 } 2 | -------------------------------------------------------------------------------- /tests/jqt/loop-53.json: -------------------------------------------------------------------------------- 1 | { "n": 4 } 2 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjqt-00.jqt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjqt-01.jqt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjqt-03.jqt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjqt-04.jqt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/expand/expected/mpmd-03.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjqt-02.jqt: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /tests/jqt/expr-02.json: -------------------------------------------------------------------------------- 1 | { "lang": "en_US" } 2 | -------------------------------------------------------------------------------- /tests/expand/mpjqt-00.jqt: -------------------------------------------------------------------------------- 1 | <# empty document #>& 2 | -------------------------------------------------------------------------------- /tests/expand/mpmd-01.md: -------------------------------------------------------------------------------- 1 | <# empty document #>& 2 | -------------------------------------------------------------------------------- /tests/jqt/expr-01.jqt: -------------------------------------------------------------------------------- 1 | The value of pi is {{.pi}}. 2 | -------------------------------------------------------------------------------- /tests/jqt/expr-01.json: -------------------------------------------------------------------------------- 1 | { "pi": 3.14159265359 } 2 | -------------------------------------------------------------------------------- /tests/jqt/expr-51.json: -------------------------------------------------------------------------------- 1 | { "pi": 3.14159265359 } 2 | -------------------------------------------------------------------------------- /tests/jqt/generated/.gitignore: -------------------------------------------------------------------------------- 1 | *.txt 2 | *.jqt 3 | -------------------------------------------------------------------------------- /tests/jqt/cond-01.json: -------------------------------------------------------------------------------- 1 | { "updated": "2016-06-26" } 2 | -------------------------------------------------------------------------------- /tests/jqt/cond-51.json: -------------------------------------------------------------------------------- 1 | { "updated": "2016-06-26" } 2 | -------------------------------------------------------------------------------- /tests/jqt/expr-51.jqt: -------------------------------------------------------------------------------- 1 | {%.pi%}The value of pi is {{.}}. 2 | -------------------------------------------------------------------------------- /tests/jqt/expected/loop-53.txt: -------------------------------------------------------------------------------- 1 | 0 2 | 1 3 | 2 4 | 3 5 | 6 | -------------------------------------------------------------------------------- /tests/jqt/expected/cond-02.txt: -------------------------------------------------------------------------------- 1 |
{{.description}} 9 | {{ .updated | fromdate | strftime("%B %Y") }}
10 |20 | 21 | Could be [_jq_][JQ] the basis for a web template engine? 22 | Let’s explore… 23 | 24 | ## _jq_ 25 | 26 | [_jq_][JQ] have nice features like string interpolation and implicit backtracking. 27 | Mixed with the help of some syntactic sugar a powerful template engine appear. 28 | Imagine the following interpolation strings, in a [_jq_][JQ] program, 29 | separated with the comma operator: 30 | 31 | ### Simple expansion 32 | 33 | ```html 34 | ..., "Editing is a rewording activity.
— Alan J. Perlis
<\/details><\/p>/<\/details>/' \
71 | -e 's/^/
/' \
72 | -e 's/<\/summary><\/p>/<\/summary>/'
73 | endef
74 |
75 | #
76 | # Extra prerequisites for HTML pages.
77 | #
78 |
79 | $(PagesHTML): $(Meta)/phase3.make \
80 | | $$(dir $$@)
81 |
82 | # Content example for `$(Meta)/phase3.make`:
83 | ########################################################################
84 | # __phase_3 := 1
85 | #
86 | # %.html: /tmp/jqt/%.html ;
87 | # blog/%.html: /tmp/jqt/blog/%.html ;
88 | #
89 | # /tmp/jqt/content.html: content/content.md content/macros.m content/LINKS.txt content/FLOW.txt content/opt/[4DdiT].txt .meta/snippets.json
90 | # $(info ==> $@)
91 | # $(JQT) -d $< -jsnippets:snippets.json -jpage:pages/content.json $(Layouts)/page-toc.html | $(DETAILS) > $@
92 | # /tmp/jqt/blog/2017-04-13-hello.html: content/blog/2017-04-13-hello.md content/macros.m content/LINKS.txt .meta/snippets.json
93 | # $(info ==> $@)
94 | # $(JQT) -d $< -jsnippets:snippets.json -jpage:pages/blog/2017-04-13-hello.json $(Layouts)/page.html | $(DETAILS) > $@
95 |
96 | # Content example for `$(Meta)/phase3d.make`:
97 | ########################################################################
98 | # /tmp/jqt/content.html: blocks/body/_toc/markup.html blocks/content/markup.html blocks/footer/markup.html blocks/header/markup.html blocks/license/markup.html blocks/logo/markup.html blocks/menu-bar/markup.html blocks/repository/markup.html blocks/toc/markup.html layouts/default.html layouts/page-toc.html
99 | # /tmp/jqt/data.html: blocks/body/_toc/markup.html blocks/content/markup.html blocks/footer/markup.html blocks/header/markup.html blocks/license/markup.html blocks/logo/markup.html blocks/menu-bar/markup.html blocks/repository/markup.html blocks/toc/markup.html layouts/default.html layouts/page-toc.html
100 |
101 | endif # __phase_3
102 |
103 | # vim:ai:sw=8:ts=8:noet:fileencoding=utf8:syntax=make
104 |
--------------------------------------------------------------------------------
/share/milligram/grid.css:
--------------------------------------------------------------------------------
1 | // Adapted (with some renaming experiments) from:
2 | /*!
3 | * Milligram v1.3.0
4 | * http://milligram.github.io
5 | *
6 | * Copyright (c) 2016 CJ Patoilo
7 | * Licensed under the MIT license
8 | */
9 |
10 | // Grid
11 | // ––––––––––––––––––––––––––––––––––––––––––––––––––
12 |
13 | // .container is main centered wrapper with a max width of 112.0rem (1120px)
14 | &BEM{#container} {
15 | margin: 0 auto;
16 | max-width: 112.0rem;
17 | padding: 0 2.0rem;
18 | position: relative;
19 | width: 100%;
20 | }
21 |
22 | // Using flexbox for the grid, inspired by Philip Walton:
23 | // http://philipwalton.github.io/solved-by-flexbox/demos/grids/
24 | // By default each .column within a .row will evenly take up
25 | // available width, and the height of each .column with take
26 | // up the height of the tallest .column in the same .row
27 | &BEM{#row} {
28 | display: flex;
29 | flex-direction: column;
30 | padding: 0;
31 | width: 100%;
32 | }
33 |
34 | &BEM{#row}{}{no-padding} {
35 | padding: 0;
36 | }
37 |
38 | &BEM{#row}{}{no-padding}{> &BEM{#column}} {
39 | padding: 0;
40 | }
41 |
42 | &BEM{#row}{}{wrap} {
43 | flex-wrap: wrap;
44 | }
45 |
46 | // Vertically Align Columns
47 | // .row-align-* vertically aligns every .column in the .row
48 | &BEM{#row}{}{align-top} {
49 | align-items: flex-start;
50 | }
51 |
52 | &BEM{#row}{}{align-bottom} {
53 | align-items: flex-end;
54 | }
55 |
56 | &BEM{#row}{}{align-center} {
57 | align-items: center;
58 | }
59 |
60 | &BEM{#row}{}{align-stretch} {
61 | align-items: stretch;
62 | }
63 |
64 | &BEM{#row}{}{align-baseline} {
65 | align-items: baseline;
66 | }
67 |
68 | // JJOR: original = .row .col..., removed .row
69 | &BEM{#column} {
70 | display: block;
71 | // IE 11 required specifying the flex-basis otherwise it breaks mobile
72 | flex: 1 1 auto;
73 | margin-left: 0;
74 | max-width: 100%;
75 | width: 100%;
76 | }
77 |
78 | // Column Offsets
79 | &define{_col_offset}{
80 | // JJOR: original = .row .col..., removed .row
81 | &BEM{#column}{}{offset-$1} {
82 | margin-left: $2;
83 | }
84 | }
85 |
86 | &_col_offset{10}{10%}
87 | &_col_offset{20}{20%}
88 | &_col_offset{25}{25%}
89 | &_col_offset{33}{33.3333%}
90 | &_col_offset{34}{33.3333%}
91 | &_col_offset{50}{50%}
92 | &_col_offset{66}{66.6666%}
93 | &_col_offset{67}{66.6666%}
94 | &_col_offset{75}{75%}
95 | &_col_offset{80}{80%}
96 | &_col_offset{90}{90%}
97 |
98 | // Explicit Column Percent Sizes
99 | // By default each grid column will evenly distribute
100 | // across the grid. However, you can specify individual
101 | // columns to take up a certain size of the available area
102 | &define{_col_size}{
103 | // JJOR: original = .row .col..., removed .row
104 | &BEM{#column}{}{size-$1} {
105 | flex: 0 0 $2;
106 | max-width: $2;
107 | }
108 | }
109 |
110 | &_col_size{10}{10%}
111 | &_col_size{20}{20%}
112 | &_col_size{25}{25%}
113 | &_col_size{33}{33.3333%}
114 | &_col_size{34}{33.3333%}
115 | &_col_size{50}{50%}
116 | &_col_size{66}{66.6666%}
117 | &_col_size{67}{66.6666%}
118 | &_col_size{75}{75%}
119 | &_col_size{80}{80%}
120 | &_col_size{90}{90%}
121 |
122 | // .column-align-* vertically aligns an individual .column
123 | // JJOR: original = .C .C-m (bug?), changed to .C.C-m
124 | // JJOR: original = .row .col..., removed .row
125 | &BEM{#column}{}{align-top} {
126 | align-self: flex-start;
127 | }
128 |
129 | &BEM{#column}{}{align-bottom} {
130 | align-self: flex-end;
131 | }
132 |
133 | &BEM{#column}{}{align-center} {
134 | align-self: center;
135 | }
136 |
137 | // Larger than mobile screen
138 | @media (min-width: 40rem) { // Safari desktop has a bug using `rem`, but Safari mobile works
139 | &BEM{#row} {
140 | flex-direction: row;
141 | margin-left: -1.0rem;
142 | width: calc(100% + 2.0rem);
143 | }
144 | // JJOR: original = .row .col..., removed .row
145 | &BEM{#column} {
146 | margin-bottom: inherit;
147 | padding: 0 1.0rem;
148 | }
149 | }
150 |
151 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss
152 |
--------------------------------------------------------------------------------
/bin/sake:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # Wraps GNU Make
5 | #
6 |
7 | ########################################################################
8 | # Bash options
9 | ########################################################################
10 |
11 | set -o errexit -o noglob -o nounset -o pipefail
12 |
13 | shopt -s expand_aliases
14 |
15 | ########################################################################
16 | # Environment
17 | ########################################################################
18 |
19 | # Imported from environment if defined; otherwise use default value
20 | declare -ri NCORES=${NCORES:-2}
21 |
22 | # Exported to use in makefiles and Sakefile
23 | declare -xr JQTLIB='/usr/local/share/jqt'
24 |
25 | ########################################################################
26 | # Check project on current directory
27 | ########################################################################
28 |
29 | declare CONFIGURATION_FILE
30 |
31 | check() {
32 | # Sakefile must exist
33 | if test ! -e Sakefile; then
34 | echo 1>&2 "sake: no \`Sakefile\` found."
35 | exit 1
36 | fi
37 |
38 | # Configuration file must exist
39 | if test -e config.yaml; then
40 | CONFIGURATION_FILE=config.yaml
41 | elif test -e config.json; then
42 | CONFIGURATION_FILE=config.json
43 | else
44 | echo 1>&2 "sake: no \`config.yaml\` or \`config.json\` file found."
45 | exit 1
46 | fi
47 | }
48 |
49 | ########################################################################
50 | # Commands
51 | ########################################################################
52 |
53 | list() {
54 | make -f Sakefile -np 2>&1 |
55 | grep -v '^[SmM]akefile' |
56 | awk '/^[^ \t.%][-A-Za-z0-9_.]*:/ { print $1 }' |
57 | sort --unique |
58 | sed 's/:\+$//' |
59 | pr --omit-pagination --width=50 --columns=4 --across
60 | } 1>&2
61 |
62 | help() {
63 | echo 'Usage: sake [command] [[options] [variable=definition] ...]'
64 | echo -e '\nCommands, builtin and user defined:\n'
65 | list
66 | echo -e '\nSee the manpage for full documentation.'
67 | } 1>&2
68 |
69 | dag() {
70 | make -f Sakefile -Bdn \
71 | | sed -n \
72 | -e "s/'//g" \
73 | -e 's/\.$//' \
74 | -e 's/Considering target file //p'
75 | }
76 |
77 | new() {
78 | local name=$1 skel=$2
79 |
80 | [[ -d "$name" ]] && {
81 | echo 1>&2 "sake: pathname \`$name\` exists!"
82 | exit 1
83 | }
84 | case $skel in
85 | basic|blog)
86 | ;;
87 | *)
88 | echo 1>&2 "sake: unknown skeleton \`$skel\`!"
89 | exit 1
90 | ;;
91 | esac
92 |
93 | #mkdir -p "$name"
94 | #cd "$name"
95 | #cp -r $JQTLIB/skel-$skel/* .
96 |
97 | echo 1>&2 "sake: Target \`new\` not implemented."
98 | }
99 |
100 | ########################################################################
101 | # Run
102 | ########################################################################
103 |
104 | # Options to gmake
105 | declare -ra makeflags=(
106 | --jobs=$(( NCORES * 150 / 100 )) # NCORES * 1.5
107 | --makefile=Sakefile
108 | --output-sync=target
109 | )
110 |
111 | # Exec gmake
112 | alias _sake='exec make "${makeflags[@]}"'
113 |
114 | # Default command: `build`
115 | [[ $# == 0 ]] && set -- build
116 |
117 | # Check if != new
118 | [[ $1 == new ]] || check
119 |
120 | # Run _sake
121 | case $1 in
122 | help) help; exit 0
123 | ;;
124 | list) list; exit 0
125 | ;;
126 | dag) dag; exit 0
127 | ;;
128 | new)
129 | shift
130 | name=site skel=basic
131 | while (( $# > 0 )); do
132 | case "$1" in
133 | name=?*) name=${1#name=}; shift ;;
134 | skel=?*) skel=${1#skel=}; shift ;;
135 | *) break 2 ;; # error?
136 | esac
137 | done
138 | new $name $skel
139 | exit 0
140 | ;;
141 | touch)
142 | touch $CONFIGURATION_FILE
143 | shift; _sake build "$@"
144 | ;;
145 | clober)
146 | shift; _sake clobber "$@"
147 | ;;
148 | config)
149 | shift; _sake configure "$@"
150 | ;;
151 | *) _sake "$@"
152 | ;;
153 | esac
154 |
155 | # vim:ai:sw=4:ts=4:et:syntax=sh
156 |
--------------------------------------------------------------------------------
/share/milligram/COLORNAMES.m:
--------------------------------------------------------------------------------
1 | // CSS named colors
2 | &define{Black}{ #000000}
3 | &define{Navy}{ #000080}
4 | &define{DarkBlue}{ #00008B}
5 | &define{MediumBlue}{ #0000CD}
6 | &define{Blue}{ #0000FF}
7 | &define{DarkGreen}{ #006400}
8 | &define{Green}{ #008000}
9 | &define{Teal}{ #008080}
10 | &define{DarkCyan}{ #008B8B}
11 | &define{DeepSkyBlue}{ #00BFFF}
12 | &define{DarkTurquoise}{ #00CED1}
13 | &define{MediumSpringGreen}{ #00FA9A}
14 | &define{Lime}{ #00FF00}
15 | &define{SpringGreen}{ #00FF7F}
16 | &define{Aqua}{ #00FFFF}
17 | &define{Cyan}{ #00FFFF}
18 | &define{MidnightBlue}{ #191970}
19 | &define{DodgerBlue}{ #1E90FF}
20 | &define{LightSeaGreen}{ #20B2AA}
21 | &define{ForestGreen}{ #228B22}
22 | &define{SeaGreen}{ #2E8B57}
23 | &define{DarkSlateGray}{ #2F4F4F}
24 | &define{DarkSlateGrey}{ #2F4F4F}
25 | &define{LimeGreen}{ #32CD32}
26 | &define{MediumSeaGreen}{ #3CB371}
27 | &define{Turquoise}{ #40E0D0}
28 | &define{RoyalBlue}{ #4169E1}
29 | &define{SteelBlue}{ #4682B4}
30 | &define{DarkSlateBlue}{ #483D8B}
31 | &define{MediumTurquoise}{ #48D1CC}
32 | &define{Indigo}{ #4B0082}
33 | &define{DarkOliveGreen}{ #556B2F}
34 | &define{CadetBlue}{ #5F9EA0}
35 | &define{CornflowerBlue}{ #6495ED}
36 | &define{RebeccaPurple}{ #663399}
37 | &define{MediumAquaMarine}{ #66CDAA}
38 | &define{DimGray}{ #696969}
39 | &define{DimGrey}{ #696969}
40 | &define{SlateBlue}{ #6A5ACD}
41 | &define{OliveDrab}{ #6B8E23}
42 | &define{SlateGray}{ #708090}
43 | &define{SlateGrey}{ #708090}
44 | &define{LightSlateGray}{ #778899}
45 | &define{LightSlateGrey}{ #778899}
46 | &define{MediumSlateBlue}{ #7B68EE}
47 | &define{LawnGreen}{ #7CFC00}
48 | &define{Chartreuse}{ #7FFF00}
49 | &define{Aquamarine}{ #7FFFD4}
50 | &define{Maroon}{ #800000}
51 | &define{Purple}{ #800080}
52 | &define{Olive}{ #808000}
53 | &define{Gray}{ #808080}
54 | &define{Grey}{ #808080}
55 | &define{SkyBlue}{ #87CEEB}
56 | &define{LightSkyBlue}{ #87CEFA}
57 | &define{BlueViolet}{ #8A2BE2}
58 | &define{DarkRed}{ #8B0000}
59 | &define{DarkMagenta}{ #8B008B}
60 | &define{SaddleBrown}{ #8B4513}
61 | &define{DarkSeaGreen}{ #8FBC8F}
62 | &define{LightGreen}{ #90EE90}
63 | &define{MediumPurple}{ #9370DB}
64 | &define{DarkViolet}{ #9400D3}
65 | &define{PaleGreen}{ #98FB98}
66 | &define{DarkOrchid}{ #9932CC}
67 | &define{YellowGreen}{ #9ACD32}
68 | &define{Sienna}{ #A0522D}
69 | &define{Brown}{ #A52A2A}
70 | &define{DarkGray}{ #A9A9A9}
71 | &define{DarkGrey}{ #A9A9A9}
72 | &define{LightBlue}{ #ADD8E6}
73 | &define{GreenYellow}{ #ADFF2F}
74 | &define{PaleTurquoise}{ #AFEEEE}
75 | &define{LightSteelBlue}{ #B0C4DE}
76 | &define{PowderBlue}{ #B0E0E6}
77 | &define{FireBrick}{ #B22222}
78 | &define{DarkGoldenRod}{ #B8860B}
79 | &define{MediumOrchid}{ #BA55D3}
80 | &define{RosyBrown}{ #BC8F8F}
81 | &define{DarkKhaki}{ #BDB76B}
82 | &define{Silver}{ #C0C0C0}
83 | &define{MediumVioletRed}{ #C71585}
84 | &define{IndianRed}{ #CD5C5C}
85 | &define{Peru}{ #CD853F}
86 | &define{Chocolate}{ #D2691E}
87 | &define{Tan}{ #D2B48C}
88 | &define{LightGray}{ #D3D3D3}
89 | &define{LightGrey}{ #D3D3D3}
90 | &define{Thistle}{ #D8BFD8}
91 | &define{Orchid}{ #DA70D6}
92 | &define{GoldenRod}{ #DAA520}
93 | &define{PaleVioletRed}{ #DB7093}
94 | &define{Crimson}{ #DC143C}
95 | &define{Gainsboro}{ #DCDCDC}
96 | &define{Plum}{ #DDA0DD}
97 | &define{BurlyWood}{ #DEB887}
98 | &define{LightCyan}{ #E0FFFF}
99 | &define{Lavender}{ #E6E6FA}
100 | &define{DarkSalmon}{ #E9967A}
101 | &define{Violet}{ #EE82EE}
102 | &define{PaleGoldenRod}{ #EEE8AA}
103 | &define{LightCoral}{ #F08080}
104 | &define{Khaki}{ #F0E68C}
105 | &define{AliceBlue}{ #F0F8FF}
106 | &define{HoneyDew}{ #F0FFF0}
107 | &define{Azure}{ #F0FFFF}
108 | &define{SandyBrown}{ #F4A460}
109 | &define{Wheat}{ #F5DEB3}
110 | &define{Beige}{ #F5F5DC}
111 | &define{WhiteSmoke}{ #F5F5F5}
112 | &define{MintCream}{ #F5FFFA}
113 | &define{GhostWhite}{ #F8F8FF}
114 | &define{Salmon}{ #FA8072}
115 | &define{AntiqueWhite}{ #FAEBD7}
116 | &define{Linen}{ #FAF0E6}
117 | &define{LightGoldenRodYellow}{ #FAFAD2}
118 | &define{OldLace}{ #FDF5E6}
119 | &define{Red}{ #FF0000}
120 | &define{Fuchsia}{ #FF00FF}
121 | &define{Magenta}{ #FF00FF}
122 | &define{DeepPink}{ #FF1493}
123 | &define{OrangeRed}{ #FF4500}
124 | &define{Tomato}{ #FF6347}
125 | &define{HotPink}{ #FF69B4}
126 | &define{Coral}{ #FF7F50}
127 | &define{DarkOrange}{ #FF8C00}
128 | &define{LightSalmon}{ #FFA07A}
129 | &define{Orange}{ #FFA500}
130 | &define{LightPink}{ #FFB6C1}
131 | &define{Pink}{ #FFC0CB}
132 | &define{Gold}{ #FFD700}
133 | &define{PeachPuff}{ #FFDAB9}
134 | &define{NavajoWhite}{ #FFDEAD}
135 | &define{Moccasin}{ #FFE4B5}
136 | &define{Bisque}{ #FFE4C4}
137 | &define{MistyRose}{ #FFE4E1}
138 | &define{BlanchedAlmond}{ #FFEBCD}
139 | &define{PapayaWhip}{ #FFEFD5}
140 | &define{LavenderBlush}{ #FFF0F5}
141 | &define{SeaShell}{ #FFF5EE}
142 | &define{Cornsilk}{ #FFF8DC}
143 | &define{LemonChiffon}{ #FFFACD}
144 | &define{FloralWhite}{ #FFFAF0}
145 | &define{Snow}{ #FFFAFA}
146 | &define{Yellow}{ #FFFF00}
147 | &define{LightYellow}{ #FFFFE0}
148 | &define{Ivory}{ #FFFFF0}
149 | &define{White}{ #FFFFFF}
150 | // vim:syntax=scss:ts=32
151 |
--------------------------------------------------------------------------------
/docs/content/engine.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Engine
3 | title: The jqt template engine
4 | description: jqt orchestrates several shell utilities to transform MarkDown text and YAML or JSON data into a final HTML page.
5 | keywords: jqt, jq, YAML, gpp, preprocessing, template engine
6 | updated: "2016-08-28T10:27:09Z"
7 | Layout: page-toc
8 | Dependencies: [content/FLOW.txt, "content/opt/[4CDdeHhIijLMmPprSTtVw].txt"]
9 | ---
10 | <%include content/macros.m>&
11 | <%include content/LINKS.txt>&
12 |
13 | # Template engine
14 |
15 | As the [Wikipedia says](https://en.wikipedia.org/wiki/Template_processor),
16 |
a template engine is
17 | software designed to combine one or more templates with a data model to produce
18 | one or more result documents
. <%cite jqt> fully satisfies this definition.
19 |
20 | ## Implementation
21 |
22 | <%cite jqt> orchestrates several shell utilities to transform [MarkDown][MARKDOWN] text and
23 | [YAML][YAML] or [JSON][JSON] data into a final HTML page. The transformation is driven by a template,
24 | where HTML is mixed with [_jq_][JQ] snippets to implement the transformation logic.
25 | This diagram shows how document, template and data inputs (on the left) are combined by
26 | <%cite jqt> to produce the final HTML output:
27 |
28 | <%include content/FLOW.txt>
29 |
30 | The command `jqt` is a shell script executed by `bash`.
31 | The external shell commands called by `jqt` are `cat`, `gpp`, `jq`, `mkdir`,
32 | `mkfifo`, `pandoc`, `python`, `rm`, `sed`, `sleep` and `tee`.
33 |
34 | `jqt` has been tested with [Bash 4.3][BASH], [GNU sed 4.2][SED], [GPP 2.24][GPP],
35 | [jq 1.5][JQ] and [Pandoc 1.13][PANDOC]. A small Python snippet is used which depends
36 | on the modules `json` (introduced with [Python 2.6](https://docs.python.org/2.6/))
37 | and `yaml` ([PyYAML](http://pyyaml.org/) implementation).
38 | The project uses [GNU Make][MAKE] on several development activities, but `make`
39 | is not necessary to run `jqt`.
40 |
41 | ## Invoking <%cite jqt>
42 |
43 | ### Synopsis
44 |
45 | `jqt` accepts several options and can be called with zero, one or two filename
46 | arguments. The usage possibilities are:
47 |
48 | | **jqt** [**-h** | **--help** | **-p** | **-V** | **--version**]
49 | | **jqt** [_options_] < _infile_ > _result_
50 | | **jqt** [_options_] _infile_ > _result_
51 | **jqt** [_options_] _infile_ _result_
52 |
53 | ### Options
54 |
55 | #### Preprocessor options
56 |
57 | <%include content/opt/D.txt>
58 | <%include content/opt/I.txt>
59 | <%include content/opt/P.txt>
60 |
61 | #### Template options
62 |
63 | <%include content/opt/L.txt>
64 | <%include content/opt/i.txt>
65 | <%include content/opt/j.txt>
66 |
67 | #### Document options
68 |
69 | <%include content/opt/4.txt>
70 | <%include content/opt/d.txt>
71 | <%include content/opt/w.txt>
72 |
73 | #### Data options
74 |
75 | <%include content/opt/M.txt>
76 | <%include content/opt/m.txt>
77 | <%include content/opt/T.txt>
78 |
79 | #### Debugging options
80 |
81 | <%include content/opt/C.txt>
82 | <%include content/opt/H.txt>
83 | <%include content/opt/S.txt>
84 |
85 | #### Information options
86 |
87 | <%include content/opt/h.txt>
88 | <%include content/opt/p.txt>
89 | <%include content/opt/V.txt>
90 |
91 | ## Preprocessing
92 |
93 | One distinctive feature of <%cite jqt> is the text expansion, using [GPP][GPP], applied to almost
94 | all kinds of input files.
95 | Also, <%cite jqt> can be used as a standalone
96 | preprocessor thanks to the `-P` option.
97 |
98 | <%cite jqt> uses two different syntaxes for macros, one for
99 | [<%cite jqt> templates](./structure.html#preprocessing) and
100 | [MarkDown documents](./content.html#preprocessing)
101 | and another for [JSON and CSS](./data.html#preprocessing) files.
102 | The following table summarizes the syntax of macro calls:
103 |
104 | JQT and MarkDown JSON and CSS
105 | --------------- ---------------- ----------------
106 | Macro calls `<%m>` `&m`
107 | `<%m x y>` `&m{x}{y}`
108 | Macro parameters `$1`...`$9` `$1`...`$9`
109 | Interpolation in arguments `" "`
110 | Escape in arguments `' '`
111 |
112 | Table: **Summary of macro syntax**
113 |
114 | The following table summarizes the syntax of text skips:
115 |
116 | JQT templates MarkDown content JSON documents CSS stylesheets
117 | ------------------ ------------- ---------------- -------------- ---------------
118 | Continuation lines `&` `&` `&` `&`
119 | Block comment `<# #>` `<# #>` `/* */` `/* */`
120 | Line comment `//` `//`
121 | Bypass[^1] `` ``
122 | `` ` ` ``
123 | \\n```
124 | `\n~~~`
125 | Escape[^2] `` ` ` `` `` ` ` ``
126 | String[^3] `{% %}` `" "` `" "`
127 | `{{ }}` `' '`
128 | `{# #}`
129 |
130 | Table: **Summary of text skips**
131 |
132 | [^1]: Text copied verbatim.
133 | [^2]: Quotes removed, text no expanded.
134 | [^3]: Quotes not removed, text expanded.
135 |
136 | <#
137 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown
138 | #>
139 |
--------------------------------------------------------------------------------
/share/sake.d/phase2.make:
--------------------------------------------------------------------------------
1 | ########################################################################
2 | # phase2.make -- Build metadata from filesystem introspection.
3 | #
4 | # Variables defined in $(Meta)/phase2.make:
5 | # __phase_2
6 | # data_csv
7 | # data_json
8 | # data_md
9 | # data_yaml
10 | # destination_paths
11 | # metadata_paths
12 | # PagesHTML
13 | # PagesJSON
14 | #
15 | # Rules defined in $(Meta)/phase2.make:
16 | # metadata JSON files for each HTML page
17 | #
18 | # Variables defined in $(MDIR)/phase2.make:
19 | # DataFiles
20 | #
21 | # Rules defined in $(MDIR)/phase2.make:
22 | # $(data_csv)
23 | # $(data_json)
24 | # $(data_md)
25 | # $(data_yaml)
26 | # $(destination_paths)
27 | # $(metadata_paths)
28 | # $(Meta)/content.text
29 | # $(Meta)/data.text
30 | # $(Meta)/phase2.make
31 | # $(Meta)/pages-by-id.json
32 |
33 | SUPER := $(Meta)/phase1.make
34 |
35 | ########################################################################
36 | # Create makefile defining global variables about pathnames and rules to
37 | # generate JSON metadata files for each page.
38 | ########################################################################
39 |
40 | #
41 | # Create `$(Meta)/phase2.make` from `find` output using `$(MDIR)/phase2.jq`.
42 | #
43 | $(Meta)/phase2.make: $(SUPER) $(THIS)
44 | $(Meta)/phase2.make: $(Meta)/content.text $(Meta)/data.text $(SCRIPT)
45 | $(info ==> $@)
46 | jq --raw-input \
47 | --raw-output \
48 | --slurp \
49 | --from-file $(MDIR)/phase2.jq \
50 | --arg DF "$$(<$(Meta)/data.text )" \
51 | --arg Content $(Content) \
52 | --arg Data $(Data) \
53 | --arg Root $(Root) \
54 | --arg Meta $(Meta) \
55 | < $< > $@
56 |
57 | # Do not preserve!
58 | .INTERMEDIATE: $(Meta)/content.text $(Meta)/data.text
59 |
60 | $(Meta)/content.text: $(THIS)
61 | $(info ==> $@)
62 | find $(Content) -type f -a \
63 | -name '[!_]*.md' -o \
64 | -name '[!_]*.mkd' -o \
65 | -name '[!_]*.markdown' \
66 | > $@
67 |
68 | $(Meta)/data.text: $(THIS)
69 | $(info ==> $@)
70 | find $(Data) -name '*.*' > $@
71 |
72 | ifdef __phase_2
73 |
74 | #
75 | # Variables used when building JSON files in `$(Meta)/phase2.make`.
76 | #
77 |
78 | define EXTRACT_FRONT_MATTER =
79 | sed -n -e '1d' \
80 | -e '/^---$$/q' \
81 | -e '/^\.\.\.$$/q' \
82 | -e '/^\#/d' \
83 | -e 'p'
84 | endef
85 |
86 | define BUILD_PAGE_JSON
87 | yaml2json | \
88 | jq --sort-keys \
89 | --arg Source $< \
90 | --arg Target $@ \
91 | --arg Meta $(Meta) \
92 | --slurpfile config $(Meta)/config.json \
93 | --from-file $(MDIR)/phase2_page.jq
94 | endef
95 |
96 | #
97 | # Extra prerequisites for JSON metadata pages.
98 | #
99 |
100 | $(PagesJSON): $(Meta)/config.json $(MDIR)/phase2_page.jq $(THIS) \
101 | | $$(dir $$@)
102 |
103 | # Content example for `$(Meta)/phase2.make`:
104 | ########################################################################
105 | # __phase_2 := 1
106 | #
107 | # destination_paths := /tmp/jqt/ /tmp/jqt/blog/
108 | # metadata_paths := .meta/pages/ .meta/pages/blog/
109 | #
110 | # data_md := .meta/snippets.json
111 | # data_yaml :=
112 | # data_json :=
113 | # data_csv :=
114 | #
115 | # PagesHTML := /tmp/jqt/content.html /tmp/jqt/data.html /tmp/jqt/index.html /tmp/jqt/engine.html /tmp/jqt/structure.html /tmp/jqt/404.html /tmp/jqt/blog/2017-04-13-hello.html /tmp/jqt/blog/index.html
116 | # PagesJSON := .meta/pages/content.json .meta/pages/data.json .meta/pages/index.json .meta/pages/engine.json .meta/pages/structure.json .meta/pages/404.json .meta/pages/blog/2017-04-13-hello.json .meta/pages/blog/index.json
117 | #
118 | # .meta/pages/content.json: content/content.md
119 | # $(info ==> $@)
120 | # @$(EXTRACT_FRONT_MATTER) < $< | $(BUILD_PAGE_JSON) > $@
121 | # ...
122 | # .meta/pages/blog/2017-04-13-hello.json: content/blog/2017-04-13-hello.md
123 | # $(info ==> $@)
124 | # @$(EXTRACT_FRONT_MATTER) < $< | $(BUILD_PAGE_JSON) > $@
125 |
126 | ########################################################################
127 | # Rules for directories.
128 | ########################################################################
129 |
130 | # Directories starting at `$(Root)/`.
131 | $(destination_paths):
132 | $(info ==> $@)
133 | mkdir --parents $@ >/dev/null 2>&1 || true
134 |
135 | # Directories starting at `$(Meta)/pages/`.
136 | $(metadata_paths):
137 | $(info ==> $@)
138 | mkdir --parents $@ >/dev/null 2>&1 || true
139 |
140 | ########################################################################
141 | # Group metadata.
142 | ########################################################################
143 |
144 | # Bundle all pages as a relation (Id => page)
145 | # TODO: use xargs? write $^ to a temp file with file()?
146 | $(Meta)/pages-by-id.json: $(PagesJSON)
147 | $(info ==> $@)
148 | cat $^ \
149 | | jq -n 'reduce inputs as $$p ({}; . + {($$p.Id):$$p})' \
150 | > $@
151 |
152 | ########################################################################
153 | # Files derived from `$(Data)/*`.
154 | ########################################################################
155 |
156 | DataFiles :=
157 |
158 | ifneq (,$(data_md))
159 | $(data_md): $(Meta)/%.json : $(Data)/%.md \
160 | | $(Meta)
161 | $(info ==> $@)
162 | jqt -T < $< | yaml2json > $@
163 | DataFiles += $(data_md)
164 | endif
165 |
166 | ifneq (,$(data_yaml))
167 | $(data_yaml): $(Meta)/%.json : $(Data)/%.yaml \
168 | | $(Meta)
169 | $(info ==> $@)
170 | yaml2json > $@
171 | DataFiles += $(data_yaml)
172 | endif
173 |
174 | ifneq (,$(data_json))
175 | $(data_json): $(Meta)/%.json : $(Data)/%.json \
176 | | $(Meta)
177 | $(info ==> $@)
178 | jqt -P json < $< > $@
179 | DataFiles += $(data_json)
180 | endif
181 |
182 | ifneq (,$(data_csv))
183 | $(data_csv): $(Meta)/%.json : $(Data)/%.csv \
184 | | $(Meta)
185 | $(info ==> $@)
186 | csv2json < $< > $@
187 | DataFiles += $(data_csv)
188 | endif
189 |
190 | endif # __phase_2
191 |
192 | # vim:ai:sw=8:ts=8:noet:fileencoding=utf8:syntax=make
193 |
--------------------------------------------------------------------------------