├── 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 |
2 | yay 3 |
4 | 5 | -------------------------------------------------------------------------------- /tests/jqt/expected/cond-03.txt: -------------------------------------------------------------------------------- 1 |
2 | yay 3 |
4 | 5 | -------------------------------------------------------------------------------- /tests/jqt/loop-01.json: -------------------------------------------------------------------------------- 1 | { "author": ["Anonymous", "Unknow"] } 2 | -------------------------------------------------------------------------------- /tests/jqt/loop-53.jqt: -------------------------------------------------------------------------------- 1 | {% range(.n) %} 2 | {{.}} 3 | {% end %} 4 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.bak 3 | *.swp 4 | /.meta/ 5 | /_site/ 6 | -------------------------------------------------------------------------------- /tests/jqt/expected/expr-01.txt: -------------------------------------------------------------------------------- 1 | The value of pi is 3.14159265359. 2 | 3 | -------------------------------------------------------------------------------- /tests/jqt/expected/expr-51.txt: -------------------------------------------------------------------------------- 1 | The value of pi is 3.14159265359. 2 | 3 | -------------------------------------------------------------------------------- /tests/jqt/loop-01.jqt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # man pages 2 | jqt.1.gz 3 | sake.1.gz 4 | # other 5 | *.swp 6 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjqt-12.jqt: -------------------------------------------------------------------------------- 1 | Lorem Ipsum 2 | 3 | 4 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjson-11.json: -------------------------------------------------------------------------------- 1 | { 2 | "price": "88" 3 | } 4 | 5 | -------------------------------------------------------------------------------- /tests/expand/expected/mpmd-13.md: -------------------------------------------------------------------------------- 1 | Lorem Ipsum 2 | 3 | 4 | -------------------------------------------------------------------------------- /tests/jqt/loop-51.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": ["Anonymous", "Unknow"] 3 | } 4 | -------------------------------------------------------------------------------- /tests/expand/expected/mpmd-14.md: -------------------------------------------------------------------------------- 1 | Lorem Ipsum 2 | ``` 3 | <%MACRO> 4 | ``` 5 | 6 | -------------------------------------------------------------------------------- /tests/expand/expected/mpmd-15.md: -------------------------------------------------------------------------------- 1 | Lorem Ipsum 2 | ~~~ 3 | <%MACRO> 4 | ~~~ 5 | 6 | -------------------------------------------------------------------------------- /tests/expand/generated/.gitignore: -------------------------------------------------------------------------------- 1 | *.md 2 | *.css 3 | *.jqt 4 | *.md 5 | *.json 6 | -------------------------------------------------------------------------------- /tests/jqt/cond-03.jqt: -------------------------------------------------------------------------------- 1 |
2 | {{if true then "yay" else "" end}} 3 |
4 | -------------------------------------------------------------------------------- /tests/jqt/expected/cond-01.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /tests/jqt/expected/cond-51.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /tests/jqt/loop-51.jqt: -------------------------------------------------------------------------------- 1 | {% .author | sort[] %} 2 | -------------------------------------------------------------------------------- /docs/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fadado/jqt/HEAD/docs/assets/favicon.ico -------------------------------------------------------------------------------- /tests/expand/expected/mpjson-10.json: -------------------------------------------------------------------------------- 1 | { 2 | "price, with discount, is": "88" 3 | } 4 | 5 | -------------------------------------------------------------------------------- /tests/expand/mpjqt-11.jqt: -------------------------------------------------------------------------------- 1 | <# partial user macro #>& 2 | <%partial youtube 7zIoLvbCCm8 420 315> 3 | -------------------------------------------------------------------------------- /tests/expand/mpmd-12.md: -------------------------------------------------------------------------------- 1 | <# partial user macro #>& 2 | <%partial youtube 7zIoLvbCCm8 420 315> 3 | -------------------------------------------------------------------------------- /tests/jqt/cond-02.jqt: -------------------------------------------------------------------------------- 1 |
2 | {% true//empty %} 3 | yay 4 | {% end %} 5 |
6 | -------------------------------------------------------------------------------- /tests/expand/mpjqt-04.jqt: -------------------------------------------------------------------------------- 1 | <# multiline #>& 2 | & 3 | <# empty #>& 4 | & 5 | <# document #>& 6 | & 7 | -------------------------------------------------------------------------------- /tests/expand/mpmd-05.md: -------------------------------------------------------------------------------- 1 | <# multiline #>& 2 | & 3 | <# empty #>& 4 | & 5 | <# document #>& 6 | & 7 | -------------------------------------------------------------------------------- /tests/jqt/loop-52.jqt: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /tests/jqt/expr-03.jqt: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{.title}} 4 | 5 | -------------------------------------------------------------------------------- /tests/expand/mpjqt-10.jqt: -------------------------------------------------------------------------------- 1 | <# partial user macro #>& 2 | <%shortcode youtube>& 3 | <%youtube 7zIoLvbCCm8 420 315> 4 | -------------------------------------------------------------------------------- /tests/expand/mpmd-11.md: -------------------------------------------------------------------------------- 1 | <# partial user macro #>& 2 | <%shortcode youtube>& 3 | <%youtube 7zIoLvbCCm8 420 315> 4 | -------------------------------------------------------------------------------- /tests/jqt/expected/loop-52.txt: -------------------------------------------------------------------------------- 1 | 7 | 8 | -------------------------------------------------------------------------------- /tests/jqt/expr-52.json: -------------------------------------------------------------------------------- 1 | { 2 | "variable": "Value with data", 3 | "item_list": [1, 2, 3, 4, 5, 6] 4 | } 5 | -------------------------------------------------------------------------------- /tests/expand/expected/mpcss-01.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | body { 5 | font: 100% Helvetica, sans_serif; 6 | color: #333; 7 | } 8 | -------------------------------------------------------------------------------- /tests/jqt/md-01.md: -------------------------------------------------------------------------------- 1 | --- 2 | author: Joan Ordinas 3 | date: Wed Jul 27 13:26:28 CEST 2016 4 | --- 5 | 6 | Hello world! 7 | -------------------------------------------------------------------------------- /tests/expand/mpmd-13.md: -------------------------------------------------------------------------------- 1 | <# skip section: XML comment #>& 2 | <%define MACRO Lorem Ipsum>& 3 | <%MACRO> 4 | 5 | -------------------------------------------------------------------------------- /tests/expand/mpmd-15.md: -------------------------------------------------------------------------------- 1 | <# skip section: code #>& 2 | <%define MACRO Lorem Ipsum>& 3 | <%MACRO> 4 | ~~~ 5 | <%MACRO> 6 | ~~~ 7 | -------------------------------------------------------------------------------- /tests/jqt/expected/loop-01.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /tests/jqt/expected/loop-51.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/content/opt/h.txt: -------------------------------------------------------------------------------- 1 | -h 2 | : Displays this message. 3 | <# 4 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 5 | #> 6 | -------------------------------------------------------------------------------- /tests/expand/mpjqt-12.jqt: -------------------------------------------------------------------------------- 1 | <# skip section: XML comment #>& 2 | <%define MACRO Lorem Ipsum>& 3 | <%MACRO> 4 | 5 | -------------------------------------------------------------------------------- /tests/expand/mpmd-10.md: -------------------------------------------------------------------------------- 1 | <# partial user macro #>& 2 | <%defeval youtube <%include youtube.m>>& 3 | <%youtube 7zIoLvbCCm8 420 315> 4 | -------------------------------------------------------------------------------- /tests/expand/mpjqt-09.jqt: -------------------------------------------------------------------------------- 1 | <# partial user macro #>& 2 | <%defeval youtube <%include youtube.m>>& 3 | <%youtube 7zIoLvbCCm8 420 315> 4 | -------------------------------------------------------------------------------- /tests/expand/mpmd-14.md: -------------------------------------------------------------------------------- 1 | <# skip section: code section #>& 2 | <%define MACRO Lorem Ipsum>& 3 | <%MACRO> 4 | ``` 5 | <%MACRO> 6 | ``` 7 | -------------------------------------------------------------------------------- /docs/content/opt/V.txt: -------------------------------------------------------------------------------- 1 | -V 2 | : Displays version information. 3 | <# 4 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 5 | #> 6 | -------------------------------------------------------------------------------- /tests/jqt/cond-01.jqt: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /tests/jqt/expected/loop-00.txt: -------------------------------------------------------------------------------- 1 | ======================= 2 | Looping blocks 3 | ======================= 4 | 5 | 2 lines 6 | 2 lines 7 | 8 | -------------------------------------------------------------------------------- /tests/jqt/loop-00.jqt: -------------------------------------------------------------------------------- 1 | ======================= 2 | Looping blocks 3 | ======================= 4 | 5 | {% range(2) %} 6 | 2 lines 7 | {% end %} 8 | -------------------------------------------------------------------------------- /docs/content/opt/p.txt: -------------------------------------------------------------------------------- 1 | -p 2 | : Prints information about Pandoc options. 3 | <# 4 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 5 | #> 6 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjqt-08.jqt: -------------------------------------------------------------------------------- 1 | 10... 2 | 9... 3 | 8... 4 | 7... 5 | 6... 6 | 5... 7 | 4... 8 | 3... 9 | 2... 10 | 1... 11 | Done! 12 | 13 | -------------------------------------------------------------------------------- /tests/expand/expected/mpmd-09.md: -------------------------------------------------------------------------------- 1 | 10... 2 | 9... 3 | 8... 4 | 7... 5 | 6... 6 | 5... 7 | 4... 8 | 3... 9 | 2... 10 | 1... 11 | Done! 12 | 13 | -------------------------------------------------------------------------------- /docs/content/opt/d.txt: -------------------------------------------------------------------------------- 1 | -d FILE 2 | : Reads the content document from *FILE*. 3 | <# 4 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 5 | #> 6 | -------------------------------------------------------------------------------- /tests/expand/mpjqt-05.jqt: -------------------------------------------------------------------------------- 1 | <%define sc $1>& 2 | <%sc Title> 3 | <%sc 'Long Title'> 4 | <%sc "Long Title"> 5 | -------------------------------------------------------------------------------- /docs/content/opt/4.txt: -------------------------------------------------------------------------------- 1 | -4, -5 2 | : Sets the output HTML version (HTML4 / HTML5). 3 | <# 4 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 5 | #> 6 | -------------------------------------------------------------------------------- /tests/expand/mpjson-11.json: -------------------------------------------------------------------------------- 1 | // XHTML entities 2 | &define{&E{k}{v}}{"&k": "&v"}& 3 | { 4 | &E{price}{88} 5 | } 6 | // vim:sw=4:ts=4:ai:et:syntax=javascript 7 | -------------------------------------------------------------------------------- /tests/expand/expected/mpcss-06.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | div { 4 | background-color: black; 5 | color: white; 6 | font-size: 12px; 7 | font-style: italic; 8 | } 9 | -------------------------------------------------------------------------------- /docs/content/opt/D.txt: -------------------------------------------------------------------------------- 1 | -D NAME=STRING 2 | : Defines the user macro *NAME* as equal to *STRING*. 3 | <# 4 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 5 | #> 6 | -------------------------------------------------------------------------------- /docs/content/opt/e.txt: -------------------------------------------------------------------------------- 1 | -e 2 | : Extracts and outputs the MarkDown document YAML front matter. 3 | <# 4 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 5 | #> 6 | -------------------------------------------------------------------------------- /docs/content/opt/i.txt: -------------------------------------------------------------------------------- 1 | -i MODULE 2 | : Includes the <%cite jq> *MODULE* in the render stage. 3 | <# 4 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 5 | #> 6 | -------------------------------------------------------------------------------- /tests/jqt/expr-03.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "en_GB", 3 | "title": "Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..." 4 | } 5 | -------------------------------------------------------------------------------- /tests/expand/mpjson-10.json: -------------------------------------------------------------------------------- 1 | // XHTML entities 2 | &define{E}{"$1": "$2"}& 3 | { 4 | &E{price, with discount, is}{88} 5 | } 6 | // vim:sw=4:ts=4:ai:et:syntax=javascript 7 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjson-12.json: -------------------------------------------------------------------------------- 1 | { 2 | "firstName": "Mister John F.", 3 | "lastName": "Kennedy", 4 | "age": 25, 5 | "gender": { "type": "male" } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /docs/content/opt/C.txt: -------------------------------------------------------------------------------- 1 | -C 2 | : Stops processing before the render stage and outputs the full JSON data model. 3 | <# 4 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 5 | #> 6 | -------------------------------------------------------------------------------- /docs/content/opt/t.txt: -------------------------------------------------------------------------------- 1 | -t 2 | : Tests presence of front matter in MarkDown (indicated in the output status). 3 | <# 4 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 5 | #> 6 | -------------------------------------------------------------------------------- /tests/expand/mpmd-06.md: -------------------------------------------------------------------------------- 1 | <# predefined user macro #>& 2 | <%define sc $1>& 3 | <%sc Title> 4 | <%sc 'Long Title'> 5 | <%sc "Long Title"> 6 | -------------------------------------------------------------------------------- /docs/content/opt/H.txt: -------------------------------------------------------------------------------- 1 | -H 2 | : Stops MarkDown processing after generating HTML (outputs several HTML fragments). 3 | <# 4 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 5 | #> 6 | -------------------------------------------------------------------------------- /docs/content/opt/S.txt: -------------------------------------------------------------------------------- 1 | -S 2 | : Stops template processing before the render stage (outputs the <%cite jq> script). 3 | <# 4 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 5 | #> 6 | -------------------------------------------------------------------------------- /docs/content/opt/r.txt: -------------------------------------------------------------------------------- 1 | -r 2 | : Removes the MarkDown document YAML front matter and outputs the document body. 3 | <# 4 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 5 | #> 6 | -------------------------------------------------------------------------------- /docs/content/opt/w.txt: -------------------------------------------------------------------------------- 1 | -w 2 | : Build the data model without input document, only from JSON and YAML input files. 3 | <# 4 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 5 | #> 6 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjqt-09.jqt: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjqt-10.jqt: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjqt-11.jqt: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjson-08.json: -------------------------------------------------------------------------------- 1 | 2 | 3 | { 4 | "firstName": "John F.", 5 | "lastName": "Kennedy", 6 | "age": 25, 7 | "gender": { "type": "male" } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /tests/expand/expected/mpmd-10.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/expand/expected/mpmd-11.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/expand/expected/mpmd-12.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/expand/expected/mpcss-02.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | .box { -webkit-border-radius: 10px; 4 | -moz-border-radius: 10px; 5 | -ms-border-radius: 10px; 6 | border-radius: 10px; 7 | } 8 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjqt-06.jqt: -------------------------------------------------------------------------------- 1 | ACA 2 | AACAA 3 | AACAA 4 | AXDXA 5 | BAXDXAB 6 | APA 7 | PYYP 8 | PYYP 9 | Q<%A C>R 10 | A<%A X>A 11 | BAX<%A X>XAB 12 | Q<%R> 13 | Q[<%A C>]R 14 | 15 | -------------------------------------------------------------------------------- /tests/expand/expected/mpmd-07.md: -------------------------------------------------------------------------------- 1 | ACA 2 | AACAA 3 | AACAA 4 | AXDXA 5 | BAXDXAB 6 | APA 7 | PYYP 8 | PYYP 9 | Q<%A C>R 10 | A<%A X>A 11 | BAX<%A X>XAB 12 | Q<%R> 13 | Q[<%A C>]R 14 | 15 | -------------------------------------------------------------------------------- /tests/expand/mpcss-01.css: -------------------------------------------------------------------------------- 1 | &define{font_stack}{Helvetica, sans_serif} 2 | &define{primary_color}{#333} 3 | 4 | // A rule 5 | body { 6 | font: 100% &font_stack; 7 | color: &primary_color; 8 | } 9 | -------------------------------------------------------------------------------- /tests/jqt/expected/expr-03.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit... 4 | 5 | 6 | -------------------------------------------------------------------------------- /docs/content/blog/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Blog 3 | title: Blog posts 4 | published: "2017-04-13T06:45:07Z" 5 | updated: "2017-04-13T06:45:07Z" 6 | Layout: blog 7 | --- 8 | 9 | <# rien de rien #> 10 | -------------------------------------------------------------------------------- /docs/content/opt/m.txt: -------------------------------------------------------------------------------- 1 | -m NAME:FILE 2 | : Adds a *FILE* in YAML or JSON format to the input data as the value of object *NAME*. 3 | <# 4 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 5 | #> 6 | -------------------------------------------------------------------------------- /share/lib.jqt.m: -------------------------------------------------------------------------------- 1 | <# 2 | # JQT macros 3 | # 4 | # Included in template expansion 5 | #>& 6 | <%include "lib-common.m">& 7 | <# 8 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=perl 9 | #>& 10 | -------------------------------------------------------------------------------- /share/lib.md.m: -------------------------------------------------------------------------------- 1 | <# 2 | # MarkDown macros 3 | # 4 | # Included in document expansion 5 | #>& 6 | <%include "lib-common.m">& 7 | <# 8 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=perl 9 | #>& 10 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjson-09.json: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | { 5 | "firstName": "Mister John F.", 6 | "lastName": "Kennedy", 7 | "age": 25, 8 | "gender": { "type": "male" } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /tests/jqt/macros-00.jqt: -------------------------------------------------------------------------------- 1 | <# define required partials #>& 2 | <%shortcode youtube>& 3 | <%shortcode analytics>& 4 | <# expand partials #>& 5 | <%youtube 7zIoLvbCCm8 420 315> 6 | <%analytics UA-8673551-2> 7 | -------------------------------------------------------------------------------- /tests/jqt/cond-51.jqt: -------------------------------------------------------------------------------- 1 | {% .published//empty | $jqt %} 2 | 3 | {% end %} 4 | {% .updated//empty %} 5 | 6 | {% end %} 7 | -------------------------------------------------------------------------------- /docs/content/404.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 404 error 3 | Layout: page 4 | --- 5 | 6 | # 404 7 | 8 | We couldn't find this page. 9 | 10 | <# 11 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 12 | #> 13 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjqt-05.jqt: -------------------------------------------------------------------------------- 1 | Title 2 | Long Title 3 | Long Title 4 | 5 | -------------------------------------------------------------------------------- /tests/expand/expected/mpmd-06.md: -------------------------------------------------------------------------------- 1 | Title 2 | Long Title 3 | Long Title 4 | 5 | -------------------------------------------------------------------------------- /tests/expand/expected/mpcss-07.css: -------------------------------------------------------------------------------- 1 | 10... 2 | 3 | 9... 4 | 5 | 8... 6 | 7 | 7... 8 | 9 | 6... 10 | 11 | 5... 12 | 13 | 4... 14 | 15 | 3... 16 | 17 | 2... 18 | 19 | 1... 20 | 21 | 22 | Done! 23 | 24 | -------------------------------------------------------------------------------- /docs/content/opt/I.txt: -------------------------------------------------------------------------------- 1 | -I DIRECTORY 2 | : Appends *DIRECTORY* to the end of the preprocessor list of directories to be 3 | searched for include files. 4 | <# 5 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 6 | #> 7 | -------------------------------------------------------------------------------- /docs/content/opt/P.txt: -------------------------------------------------------------------------------- 1 | -P LANGUAGE 2 | : Expands input file with the macro-processor (*LANGUAGE* can be `jqt`, `md`, 3 | `json`, `css` or `css-min`). 4 | <# 5 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 6 | #> 7 | -------------------------------------------------------------------------------- /tests/jqt/expr-52.jqt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{.variable | @html}} 5 | 6 | 7 | {{ .item_list | map(" "+@text) | join(",\n") }} 8 | 9 | 10 | -------------------------------------------------------------------------------- /tests/expand/mpcss-06.css: -------------------------------------------------------------------------------- 1 | &define{content}{ 2 | background-color: black; 3 | color: white; 4 | $1& 5 | } 6 | 7 | div { 8 | &content{ 9 | font-size: 12px; 10 | font-style: italic;& 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/expand/expected/mpcss-04.css: -------------------------------------------------------------------------------- 1 | .container { width: 100%; } 2 | 3 | article[role="main"] { 4 | float: left; 5 | width: 62%; 6 | } 7 | 8 | aside[role="complementary"] { 9 | float: right; 10 | width: 31%; 11 | } 12 | -------------------------------------------------------------------------------- /docs/content/opt/L.txt: -------------------------------------------------------------------------------- 1 | -L DIRECTORY 2 | : Appends *DIRECTORY* to the end of the <%cite jq> list of directories to be searched 3 | for included and imported modules. 4 | <# 5 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 6 | #> 7 | -------------------------------------------------------------------------------- /tests/jqt/expected/expr-02.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/content/opt/M.txt: -------------------------------------------------------------------------------- 1 | -M NAME:FILE 2 | : Adds a *FILE* in YAML or JSON format to the input data at the top level 3 | (*NAME* is ignored but must be present and unique). 4 | <# 5 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 6 | #> 7 | -------------------------------------------------------------------------------- /tests/expand/expected/mpcss-05.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | a { 4 | color: red; 5 | } 6 | a:visited { 7 | color: green; 8 | } 9 | a:hover { 10 | color: blue; 11 | } 12 | a:active { 13 | color: yellow; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /docs/assets/README.md: -------------------------------------------------------------------------------- 1 | # _jqt_ · The _jq_ template engine 2 | 3 | This is the documentation for _jqt_. 4 | Visit the generated web site at . 5 | 6 | 9 | -------------------------------------------------------------------------------- /tests/expand/mpcss-07.css: -------------------------------------------------------------------------------- 1 | // recursion 2 | &define{countdown}{ 3 | &if{$1}& 4 | $1... 5 | &define{_countdown}{&countdown{$1}}& 6 | &else 7 | Done! 8 | &define{_countdown}{}& 9 | &endif 10 | &_countdown{&eval{$1-1}}& 11 | }& 12 | &countdown{10}& 13 | -------------------------------------------------------------------------------- /tests/expand/mpjson-08.json: -------------------------------------------------------------------------------- 1 | /* Macros */ 2 | &define{NAME}{John F.} 3 | { 4 | "firstName": "&NAME", 5 | "lastName": "Kennedy", 6 | "age": 25, 7 | "gender": { "type": "male" } 8 | } 9 | // vim:sw=4:ts=4:ai:et:syntax=javascript 10 | -------------------------------------------------------------------------------- /tests/expand/mpjson-12.json: -------------------------------------------------------------------------------- 1 | // Macros 2 | &define{T}{Mister }& 3 | { 4 | "firstName": "&T&_{}John F.", 5 | "lastName": "Kennedy", 6 | "age": 25, 7 | "gender": { "type": "male" } 8 | } 9 | // vim:sw=4:ts=4:ai:et:syntax=javascript 10 | -------------------------------------------------------------------------------- /tests/jqt/expected/expr-52.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Value with <unsafe> data 5 | 6 | 7 | 1, 8 | 2, 9 | 3, 10 | 4, 11 | 5, 12 | 6 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/expand/mpcss-02.css: -------------------------------------------------------------------------------- 1 | &define{&border_radius{radius}}{ 2 | -webkit-border-radius: &radius; 3 | -moz-border-radius: &radius; 4 | -ms-border-radius: &radius; 5 | border-radius: &radius; 6 | } 7 | 8 | .box { &border_radius{10px} } 9 | -------------------------------------------------------------------------------- /tests/expand/mpcss-04.css: -------------------------------------------------------------------------------- 1 | .container { width: 100%; } 2 | 3 | article[role="main"] { 4 | float: left; 5 | width: &eval{(100 * 600) / 960}%; 6 | } 7 | 8 | aside[role="complementary"] { 9 | float: right; 10 | width: &eval{(100 * 300) / 960}%; 11 | } 12 | -------------------------------------------------------------------------------- /tests/expand/mpjqt-08.jqt: -------------------------------------------------------------------------------- 1 | <# recursion #>& 2 | <%define countdown 3 | <%if $1>& 4 | $1... 5 | <%define _countdown <%countdown $1>>& 6 | <%else>& 7 | Done! 8 | <%define _countdown>& 9 | <%endif>& 10 | <%_countdown <%eval $1-1>>& 11 | >& 12 | <%countdown 10>& 13 | -------------------------------------------------------------------------------- /tests/expand/mpmd-09.md: -------------------------------------------------------------------------------- 1 | <# recursion #>& 2 | <%define countdown 3 | <%if $1>& 4 | $1... 5 | <%define _countdown <%countdown $1>>& 6 | <%else>& 7 | Done! 8 | <%define _countdown>& 9 | <%endif>& 10 | <%_countdown <%eval $1-1>>& 11 | >& 12 | <%countdown 10>& 13 | -------------------------------------------------------------------------------- /tests/jqt/cond-00.json: -------------------------------------------------------------------------------- 1 | { 2 | "yes": true, 3 | "not": false, 4 | "nil": null, 5 | "string": "Neque porro quisquam", 6 | "number": 3.14159265358979323846, 7 | "array": [7,6,5,4,3,2,1 ], 8 | "object": { "b": true, "s": "Neque", "n": 3.14 } 9 | } 10 | -------------------------------------------------------------------------------- /tests/jqt/expr-00.json: -------------------------------------------------------------------------------- 1 | { 2 | "yes": true, 3 | "not": false, 4 | "nil": null, 5 | "string": "Neque porro quisquam", 6 | "number": 3.14159265358979323846, 7 | "array": [7,6,5,4,3,2,1 ], 8 | "object": { "b": true, "s": "Neque", "n": 3.14 } 9 | } 10 | -------------------------------------------------------------------------------- /tests/jqt/loop-00.json: -------------------------------------------------------------------------------- 1 | { 2 | "yes": true, 3 | "not": false, 4 | "nil": null, 5 | "string": "Neque porro quisquam", 6 | "number": 3.14159265358979323846, 7 | "array": [7,6,5,4,3,2,1 ], 8 | "object": { "b": true, "s": "Neque", "n": 3.14 } 9 | } 10 | -------------------------------------------------------------------------------- /docs/content/opt/j.txt: -------------------------------------------------------------------------------- 1 | -j NAME:MODULE 2 | : Imports the <%cite jq> *MODULE* in the render stage and define helper function 3 | named *NAME* if *MODULE* is a data module and has the suffix `.json`. 4 | <# 5 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 6 | #> 7 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # restore format tests 2 | 3 | test-csv and test-yaml fail: Python3??? 4 | 5 | setup: 6 | install python3 ??? 7 | @rpm -q --quiet python2-pyyaml || sudo dnf -y install python2-pyyaml 8 | 9 | 10 | # spin-off 11 | 12 | ``` 13 | mpp < f.mpp > f.md 14 | ``` 15 | -------------------------------------------------------------------------------- /tests/expand/mpjson-09.json: -------------------------------------------------------------------------------- 1 | /* Macros */ 2 | &define{T}{Mister } 3 | &define{NAME}{John F.} 4 | { 5 | "firstName": "&T&NAME", 6 | "lastName": "Kennedy", 7 | "age": 25, 8 | "gender": { "type": "male" } 9 | } 10 | // vim:sw=4:ts=4:ai:et:syntax=javascript 11 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjson-03.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "line1": "// this is not a comment", 4 | "line2": "this // is not a comment", 5 | "line3": "this is not a comment //", 6 | "str1": "this string has \" inside", 7 | "str2": "this string has \n inside" 8 | } 9 | 10 | -------------------------------------------------------------------------------- /tests/jqt/expr-02.jqt: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjson-04.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "comment1": "/* this is not a comment", 4 | "comment2": "this is not a comment */", 5 | "comment3": "/* this is not a comment */", 6 | "comment4": "/* this /* not a comment */", 7 | "comment5": "/* this */ not a comment */" 8 | } 9 | 10 | -------------------------------------------------------------------------------- /tests/format/yaml-04.sh: -------------------------------------------------------------------------------- 1 | # yq q YAML == s 2 | 3 | set -o errexit -o pipefail -o nounset 4 | 5 | cd $(dirname $0) 6 | 7 | # Query 8 | YQ=yq 9 | 10 | # Extract string 11 | [[ $(${YQ} -J -r '.store.bicycle.color' data/store.yaml) == 'red' ]] 12 | 13 | exit 14 | 15 | # vim:ai:sw=4:ts=4:et:syntax=sh 16 | -------------------------------------------------------------------------------- /tests/format/csv-04.sh: -------------------------------------------------------------------------------- 1 | # cq q YAML == s 2 | 3 | set -o errexit -o pipefail -o nounset 4 | 5 | cd $(dirname $0) 6 | 7 | # Query 8 | CQ=cq 9 | 10 | # Extract string 11 | (( $(${CQ} -J -r 'select(.city == "Hamel").post' data/au.csv) == 6215 )) 12 | 13 | exit 14 | 15 | # vim:ai:sw=4:ts=4:et:syntax=sh 16 | 17 | -------------------------------------------------------------------------------- /tests/expand/mpcss-05.css: -------------------------------------------------------------------------------- 1 | &define{&linx{link}{visit}{hover}{active}}{ 2 | a { 3 | color: &link; 4 | } 5 | a:visited { 6 | color: &visit; 7 | } 8 | a:hover { 9 | color: &hover; 10 | } 11 | a:active { 12 | color: &active; 13 | } 14 | } 15 | 16 | &linx{red}{green}{blue}{yellow} 17 | -------------------------------------------------------------------------------- /docs/layouts/page.html: -------------------------------------------------------------------------------- 1 | <# Default page #>& 2 | <# 3 | # Main page block for content 4 | #>& 5 | <%define BODY_BLOCK 6 | <%include blocks/body/markup.html> 7 | >& 8 | <# 9 | # Inherit default layout 10 | #>& 11 | <%include layouts/default.html>& 12 | <# 13 | vim:ts=2:sw=2:ai:et:fileencoding=utf8:syntax=perl 14 | #>& 15 | -------------------------------------------------------------------------------- /docs/content/opt/T.txt: -------------------------------------------------------------------------------- 1 | -T [NAME:FILE] 2 | : Transforms front matter YAML top level MarkDown scalar values to HTML. 3 | If *NAME:FILE* is provided add the transformed data to the input data as a value of object *NAME*. 4 | Otherwise, outputs a new YAML document. 5 | <# 6 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 7 | #> 8 | -------------------------------------------------------------------------------- /docs/layouts/blog.html: -------------------------------------------------------------------------------- 1 | <# Posts list #>& 2 | <# 3 | # Main page block for content 4 | #>& 5 | <%define BODY_BLOCK 6 | <%include blocks/body/_blog/markup.html> 7 | >& 8 | <# 9 | # Inherit default layout 10 | #>& 11 | <%include layouts/default.html>& 12 | <# 13 | vim:ts=2:sw=2:ai:et:fileencoding=utf8:syntax=perl 14 | #>& 15 | -------------------------------------------------------------------------------- /docs/blocks/content/markup.html: -------------------------------------------------------------------------------- 1 | <####################################################################### 2 | # Content 3 | ######################################################################>& 4 |
5 | {{$jqt._content}} 6 |
7 | <# 8 | vim:ts=2:sw=2:ai:et:fileencoding=utf8:syntax=html 9 | #>& 10 | -------------------------------------------------------------------------------- /docs/blocks/license/markup.html: -------------------------------------------------------------------------------- 1 | <####################################################################### 2 | # License 3 | ######################################################################>& 4 |
5 | {{snippets.footer}} 6 |
7 | <# 8 | vim:ts=2:sw=2:ai:et:fileencoding=utf8:syntax=html 9 | #>& 10 | -------------------------------------------------------------------------------- /share/vimeo.m: -------------------------------------------------------------------------------- 1 | <# 2 | # Usage: <%partial vimeo 38514156 560 315> 3 | # 4 | # $1: ID 5 | # $2: width 6 | # $3: height 7 | #>& 8 | 12 | <# 13 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=html 14 | #>& 15 | -------------------------------------------------------------------------------- /tests/format/data/person.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | firstName: John 3 | lastName: Smith 4 | age: 25 5 | address: 6 | streetAddress: 21 2nd Street 7 | city: New York 8 | state: NY 9 | postalCode: 10021 10 | phoneNumber: 11 | - type: home 12 | number: 212 555-1234 13 | - type: fax 14 | number: 646 555-4567 15 | gender: 16 | type: male 17 | -------------------------------------------------------------------------------- /docs/layouts/page-toc.html: -------------------------------------------------------------------------------- 1 | <# Page with toc markup #>& 2 | <# 3 | # Main page block for content 4 | #>& 5 | <%define BODY_BLOCK 6 | <%include blocks/body/_toc/markup.html> 7 | >& 8 | <# 9 | # Inherit default layout 10 | #>& 11 | <%include layouts/default.html>& 12 | <# 13 | vim:ts=2:sw=2:ai:et:fileencoding=utf8:syntax=perl 14 | #>& 15 | -------------------------------------------------------------------------------- /tests/expand/mpjson-03.json: -------------------------------------------------------------------------------- 1 | /* 2 | * JSON strings 3 | */ 4 | { 5 | "line1": "// this is not a comment", 6 | "line2": "this // is not a comment", 7 | "line3": "this is not a comment //", 8 | "str1": "this string has \" inside", 9 | "str2": "this string has \n inside" 10 | } 11 | // vim:sw=4:ts=4:ai:et:syntax=javascript 12 | -------------------------------------------------------------------------------- /share/youtube.m: -------------------------------------------------------------------------------- 1 | <# 2 | # Usage: <%partial youtube tcKkdNvJvAQ 560 315> 3 | # 4 | # $1: ID 5 | # $2: width 6 | # $3: height 7 | #>& 8 | 12 | <# 13 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=html 14 | #>& 15 | -------------------------------------------------------------------------------- /tests/format/csv-03.sh: -------------------------------------------------------------------------------- 1 | # jq q JSON == cq q YAML 2 | 3 | set -o errexit -o pipefail -o nounset 4 | 5 | cd $(dirname $0) 6 | 7 | # Conversions 8 | CQ=cq 9 | J2C=json2csv 10 | 11 | # Same result 12 | diff <(jq -s '.[1]' data/au.json | ${J2C}) \ 13 | <(${CQ} -s '.[1]' data/au.csv) 14 | 15 | exit 16 | 17 | # vim:ai:sw=4:ts=4:et:syntax=sh 18 | -------------------------------------------------------------------------------- /bin/json2csv: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Simple JSON to CSV conversor 4 | 5 | test $# -gt 0 && exec < $1 6 | 7 | jq --slurp --raw-output ' 8 | (.[0]//{} | keys_unsorted) as $cols | 9 | map(. as $row | $cols | map($row[.])) as $rows | 10 | $cols, $rows[] | @csv 11 | ' 12 | 13 | exit 14 | 15 | # vim:ai:sw=4:ts=4:et:fileencoding=utf-8:syntax=sh 16 | -------------------------------------------------------------------------------- /docs/blocks/body/markup.html: -------------------------------------------------------------------------------- 1 | <####################################################################### 2 | # Body simple 3 | ######################################################################>& 4 |
5 | <%include blocks/content/markup.html>& 6 |
7 | <# 8 | vim:ts=2:sw=2:ai:et:fileencoding=utf8:syntax=html 9 | #>& 10 | -------------------------------------------------------------------------------- /docs/blocks/container/style.css: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////// 2 | // Container 3 | //////////////////////////////////////////////////////////////////////// 4 | 5 | @media screen { 6 | body&SEL{#container} { 7 | max-width: 800px; 8 | } 9 | } 10 | 11 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=css 12 | -------------------------------------------------------------------------------- /tests/expand/expected/mpcss-08.css: -------------------------------------------------------------------------------- 1 | ACA 2 | AACAA 3 | AACAA 4 | AXDXA 5 | BAXDXAB 6 | APA 7 | PYYP 8 | PYYP 9 | Q&A}{C}R 10 | A&A}{X}A 11 | BAX&A}{X}XAB 12 | Q&R} 13 | Q[&A}{C}]R 14 | /* Output: 15 | ACA 16 | AACAA 17 | AACAA 18 | AXDXA 19 | BAXDXAB 20 | APA 21 | PYYP 22 | PYYP 23 | QAA C}R 24 | AAA X}A 25 | BAXAA X}XAB 26 | Q&R} 27 | Q[AA C}]R 28 | */ -------------------------------------------------------------------------------- /tests/expand/mpjson-04.json: -------------------------------------------------------------------------------- 1 | /* 2 | * JSON comments 3 | */ 4 | { 5 | "comment1": "/* this is not a comment", 6 | "comment2": "this is not a comment */", 7 | "comment3": "/* this is not a comment */", 8 | "comment4": "/* this /* not a comment */", 9 | "comment5": "/* this */ not a comment */" 10 | } 11 | // vim:sw=4:ts=4:ai:et:syntax=javascript 12 | -------------------------------------------------------------------------------- /docs/blocks/license/style.css: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////// 2 | // License 3 | //////////////////////////////////////////////////////////////////////// 4 | 5 | &BEM{license} { 6 | text-align: center; 7 | } 8 | 9 | &BEM{license} > p { 10 | margin-bottom: 0; 11 | } 12 | 13 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=css 14 | -------------------------------------------------------------------------------- /tests/expand/mpcss-03.css: -------------------------------------------------------------------------------- 1 | &define{message}{ 2 | border: 1px solid #ccc; 3 | padding: 10px; 4 | color: #333& 5 | } 6 | 7 | .message { 8 | &message; 9 | } 10 | 11 | .success { 12 | &message; 13 | border-color: green; 14 | } 15 | 16 | .error { 17 | &message; 18 | border-color: red; 19 | } 20 | 21 | .warning { 22 | &message; 23 | border-color: yellow; 24 | } 25 | -------------------------------------------------------------------------------- /docs/blocks/logo/markup.html: -------------------------------------------------------------------------------- 1 | <####################################################################### 2 | # Logo 3 | ######################################################################>& 4 | 5 | <# 6 | vim:ts=2:sw=2:ai:et:fileencoding=utf8:syntax=html 7 | #>& 8 | -------------------------------------------------------------------------------- /docs/blocks/toc/markup.html: -------------------------------------------------------------------------------- 1 | <####################################################################### 2 | # Toc 3 | ######################################################################>& 4 | 8 | <# 9 | vim:ts=2:sw=2:ai:et:fileencoding=utf8:syntax=html 10 | #>& 11 | -------------------------------------------------------------------------------- /share/milligram/image.css: -------------------------------------------------------------------------------- 1 | // Adapted 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 | // Image 11 | // –––––––––––––––––––––––––––––––––––––––––––––––––– 12 | 13 | img { 14 | max-width: 100%; 15 | } 16 | 17 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss 18 | -------------------------------------------------------------------------------- /docs/blocks/filters.jq: -------------------------------------------------------------------------------- 1 | # 2 | # Extra filters for this site 3 | # 4 | 5 | # Remove XML tags 6 | def striptags: 7 | # warning: algorithm too simplistic 8 | gsub("<[^>]*>"; "") 9 | ; 10 | 11 | def sections: 12 | # . as $pages 13 | map(.section) 14 | | unique 15 | | map(select(. != null and . != "")) 16 | ; 17 | 18 | # vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=jq 19 | -------------------------------------------------------------------------------- /tests/format/yaml-03.sh: -------------------------------------------------------------------------------- 1 | # jq q JSON == yq q YAML 2 | 3 | set -o errexit -o pipefail -o nounset 4 | 5 | cd $(dirname $0) 6 | 7 | # Conversions 8 | J2Y=json2yaml 9 | YQ=yq 10 | 11 | # Same result 12 | diff <(jq --sort-keys '.store.book[1]' data/store.json | ${J2Y}) \ 13 | <(${YQ} --sort-keys '.store.book[1]' data/store.yaml) 14 | 15 | exit 16 | 17 | # vim:ai:sw=4:ts=4:et:syntax=sh 18 | -------------------------------------------------------------------------------- /docs/blocks/body/_toc/markup.html: -------------------------------------------------------------------------------- 1 | <####################################################################### 2 | # Body with TOC 3 | ######################################################################>& 4 |
5 | <%include blocks/toc/markup.html> 6 | <%include blocks/content/markup.html> 7 |
8 | <# 9 | vim:ts=2:sw=2:ai:et:fileencoding=utf8:syntax=html 10 | #>& 11 | -------------------------------------------------------------------------------- /docs/blocks/logo/style.css: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////// 2 | // Logo 3 | //////////////////////////////////////////////////////////////////////// 4 | 5 | &BEM{logo} { 6 | font-size: 2.6rem; 7 | } 8 | 9 | &BEM{logo}{version} { 10 | font-size: 1.2rem; 11 | font-weight: bold; 12 | } 13 | 14 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=css 15 | -------------------------------------------------------------------------------- /docs/blocks/footer/markup.html: -------------------------------------------------------------------------------- 1 | <####################################################################### 2 | # Footer 3 | ######################################################################>& 4 |
5 | <%include blocks/license/markup.html>& 6 | <%include blocks/repository/markup.html>& 7 |
8 | <# 9 | vim:ts=2:sw=2:ai:et:fileencoding=utf8:syntax=html 10 | #>& 11 | -------------------------------------------------------------------------------- /tests/jqt/expected/cond-00.txt: -------------------------------------------------------------------------------- 1 | ======================= 2 | Conditional blocks 3 | ======================= 4 | 5 | _____ 6 | I expand! 7 | I expand to 'Neque porro quisquam' 8 | I expand to '3.141592653589793' 9 | I expand preserving $jqt: '3.141592653589793' 10 | _____ 11 | _____ 12 | 13 | I expand to 'Neque porro quisquam' 14 | I expand to 'Neque porro quisquam' 15 | 16 | else yes 17 | 18 | case else 19 | 20 | -------------------------------------------------------------------------------- /docs/blocks/header/markup.html: -------------------------------------------------------------------------------- 1 | <####################################################################### 2 | # Header 3 | ######################################################################>& 4 |
5 | 9 |
10 | <# 11 | vim:ts=2:sw=2:ai:et:fileencoding=utf8:syntax=html 12 | #>& 13 | -------------------------------------------------------------------------------- /tests/format/yaml-05.sh: -------------------------------------------------------------------------------- 1 | # data/person.json == (y2j data/person.yaml) 2 | 3 | set -o errexit -o pipefail -o nounset 4 | 5 | cd $(dirname $0) 6 | 7 | # Conversions 8 | Y2J=yaml2json 9 | 10 | # Slurp two files 11 | jq --sort-keys --slurp --raw-output \ 12 | '.[0] == .[1]' \ 13 | data/person.json \ 14 | <(${Y2J} data/person.yaml) \ 15 | | grep -q true 16 | 17 | exit 18 | 19 | # vim:ai:sw=4:ts=4:et:syntax=sh 20 | -------------------------------------------------------------------------------- /share/slideshare.m: -------------------------------------------------------------------------------- 1 | <# 2 | # Usage: <%partial slideshare FOuwiWHTdrs1OJ 595 485> 3 | # 4 | # $1: ID 5 | # $2: width 6 | # $3: height 7 | #>& 8 | 15 | <# 16 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=html 17 | #>& 18 | -------------------------------------------------------------------------------- /tests/format/yaml-02.sh: -------------------------------------------------------------------------------- 1 | # data/hardware.json == (j2y data/hardware.json | y2j) 2 | 3 | set -o errexit -o pipefail -o nounset 4 | 5 | cd $(dirname $0) 6 | 7 | # Conversions 8 | Y2J=yaml2json 9 | J2Y=json2yaml 10 | 11 | # Slurp two files 12 | jq --slurp --raw-output \ 13 | '.[0] == .[1]' \ 14 | data/hardware.json \ 15 | <(${J2Y} data/hardware.json | ${Y2J}) \ 16 | | grep -q true 17 | 18 | exit 19 | 20 | # vim:ai:sw=4:ts=4:et:syntax=sh 21 | -------------------------------------------------------------------------------- /tests/format/csv-01.sh: -------------------------------------------------------------------------------- 1 | # data/au.json == (j2c data/au.csv | c2j) 2 | 3 | set -o errexit -o pipefail -o nounset 4 | 5 | cd $(dirname $0) 6 | 7 | # Conversions 8 | C2J=csv2json 9 | J2C=json2csv 10 | 11 | # Slurp two files into variable 12 | jq --null-input --raw-output \ 13 | --slurpfile j1 data/au.json \ 14 | --slurpfile j2 <(${J2C} data/au.json | ${C2J}) \ 15 | '$j1 == $j2' | grep -q true 16 | 17 | exit 18 | 19 | # vim:ai:sw=4:ts=4:et:syntax=sh 20 | 21 | -------------------------------------------------------------------------------- /share/milligram/divider.css: -------------------------------------------------------------------------------- 1 | // Adapted 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 | // Divider 11 | // –––––––––––––––––––––––––––––––––––––––––––––––––– 12 | 13 | hr { 14 | border: 0; 15 | border-top: 0.1rem solid &ColorTertiary; 16 | margin: calc(&SpacingScale * 3.0rem) 0; 17 | } 18 | 19 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss 20 | -------------------------------------------------------------------------------- /docs/blocks/body/_blog/style.css: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////// 2 | // Blog posts 3 | //////////////////////////////////////////////////////////////////////// 4 | 5 | &BEM{post-excerpt} { 6 | } 7 | 8 | &BEM{post-excerpt}{title} { 9 | text-decoration: underline; 10 | } 11 | 12 | &BEM{post-excerpt}{text} { 13 | } 14 | 15 | &BEM{post-excerpt}{date} { 16 | color: &LightGrey; 17 | } 18 | 19 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=css 20 | -------------------------------------------------------------------------------- /share/milligram/link.css: -------------------------------------------------------------------------------- 1 | // Adapted 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 | // Link 11 | // –––––––––––––––––––––––––––––––––––––––––––––––––– 12 | 13 | a { 14 | color: &ColorPrimary; 15 | text-decoration: none; 16 | } 17 | 18 | a:focus, 19 | a:hover { 20 | color: &ColorSecondary; 21 | } 22 | 23 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss 24 | -------------------------------------------------------------------------------- /docs/blocks/footer/style.css: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////// 2 | // Footer 3 | //////////////////////////////////////////////////////////////////////// 4 | 5 | // shared with header 6 | &define{HorizontalRule}{0.4rem solid &ColorTertiary} 7 | 8 | &BEM{#footer} { 9 | border-top: &HorizontalRule; 10 | } 11 | 12 | @media print { 13 | &BEM{#footer} { 14 | display: none; 15 | } 16 | } 17 | 18 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=css 19 | -------------------------------------------------------------------------------- /tests/format/yaml-01.sh: -------------------------------------------------------------------------------- 1 | # data/hardware.json == (j2y data/hardware.json | y2j) 2 | 3 | set -o errexit -o pipefail -o nounset 4 | 5 | cd $(dirname $0) 6 | 7 | # Conversions 8 | Y2J=yaml2json 9 | J2Y=json2yaml 10 | 11 | # Slurp two files into variable 12 | jq --null-input --raw-output \ 13 | --slurpfile j1 data/hardware.json \ 14 | --slurpfile j2 <(${J2Y} data/hardware.json | ${Y2J}) \ 15 | '$j1 == $j2' | grep -q true 16 | 17 | exit 18 | 19 | # vim:ai:sw=4:ts=4:et:syntax=sh 20 | 21 | -------------------------------------------------------------------------------- /tests/expand/expected/mpcss-03.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | .message { 4 | border: 1px solid #ccc; 5 | padding: 10px; 6 | color: #333; 7 | } 8 | 9 | .success { 10 | border: 1px solid #ccc; 11 | padding: 10px; 12 | color: #333; 13 | border-color: green; 14 | } 15 | 16 | .error { 17 | border: 1px solid #ccc; 18 | padding: 10px; 19 | color: #333; 20 | border-color: red; 21 | } 22 | 23 | .warning { 24 | border: 1px solid #ccc; 25 | padding: 10px; 26 | color: #333; 27 | border-color: yellow; 28 | } 29 | -------------------------------------------------------------------------------- /tests/expand/mpjson-01.json: -------------------------------------------------------------------------------- 1 | { 2 | "firstName": "John", 3 | "lastName": "Smith", 4 | "age": 25, 5 | "address": { 6 | "streetAddress": "21 2nd Street", 7 | "city": "New York", 8 | "state": "NY", 9 | "postalCode": "10021" 10 | }, 11 | "phoneNumber": [ 12 | { 13 | "type": "home", 14 | "number": "212 555-1234" 15 | }, 16 | { 17 | "type": "fax", 18 | "number": "646 555-4567" 19 | } 20 | ], 21 | "gender": { 22 | "type": "male" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/format/data/person.json: -------------------------------------------------------------------------------- 1 | { 2 | "firstName": "John", 3 | "lastName": "Smith", 4 | "age": 25, 5 | "address": { 6 | "streetAddress": "21 2nd Street", 7 | "city": "New York", 8 | "state": "NY", 9 | "postalCode": 10021 10 | }, 11 | "phoneNumber": [ 12 | { 13 | "type": "home", 14 | "number": "212 555-1234" 15 | }, 16 | { 17 | "type": "fax", 18 | "number": "646 555-4567" 19 | } 20 | ], 21 | "gender": { 22 | "type": "male" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /docs/blocks/header/style.css: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////// 2 | // Header 3 | //////////////////////////////////////////////////////////////////////// 4 | 5 | // shared with footer 6 | &define{HorizontalRule}{0.4rem solid &ColorTertiary} 7 | 8 | &BEM{#header} { 9 | border-bottom: &HorizontalRule; 10 | margin-bottom: 1.5rem; 11 | } 12 | 13 | @media print { 14 | &BEM{#header} { 15 | display: none; 16 | } 17 | } 18 | 19 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=css 20 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjson-01.json: -------------------------------------------------------------------------------- 1 | { 2 | "firstName": "John", 3 | "lastName": "Smith", 4 | "age": 25, 5 | "address": { 6 | "streetAddress": "21 2nd Street", 7 | "city": "New York", 8 | "state": "NY", 9 | "postalCode": "10021" 10 | }, 11 | "phoneNumber": [ 12 | { 13 | "type": "home", 14 | "number": "212 555-1234" 15 | }, 16 | { 17 | "type": "fax", 18 | "number": "646 555-4567" 19 | } 20 | ], 21 | "gender": { 22 | "type": "male" 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjson-05.json: -------------------------------------------------------------------------------- 1 | 2 | 3 | { 4 | "firstName": "John", 5 | "lastName": "Smith", 6 | "age": 25, 7 | "address": { "streetAddress": "21 2nd Street", 8 | "city": "New York", 9 | "state": "NY", 10 | "postalCode": "10021" 11 | }, 12 | "phoneNumber": [ 13 | { 14 | "type": "home", 15 | "number": "212 555-1234" 16 | }, 17 | { 18 | "type": "fax", 19 | "number": "646 555-4567" 20 | } 21 | ], 22 | "gender": { 23 | "type": "male" 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /docs/data/snippets.md: -------------------------------------------------------------------------------- 1 | --- 2 | # identical to config.yaml title: with style 3 | title: jqt, the _jq_ template engine 4 | footer: | 5 | This website is made with [_jqt_](https://fadado.github.io/jqt/).\ 6 | _jqt_ is licensed under the [MIT](https://github.com/fadado/jqt/blob/master/LICENSE) license (code) and the 7 | [CC-BY-3.0](https://creativecommons.org/licenses/by/3.0/) license (documents). 8 | 9 | toc-title: Page contents 10 | 11 | # vim:ts=2:sw=2:ai:et:fileencoding=utf8:syntax=markdown 12 | --- 13 | -------------------------------------------------------------------------------- /share/lib.css.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSS macros 3 | // 4 | // Included in CSS expansion 5 | // 6 | &mode{push}& 7 | &mode{string}{ccc "&\n" "" ""}& 8 | &mode{string}{ccc "<#" "#>" ""}& 9 | &mode{string}{iqi "'" "'" ""}& 10 | &mode{string}{iQi "\"" "\"" ""}& 11 | &mode{user}{"<%" ">" "\B" "\B" "\W>" "<" ">" "$" ""}& 12 | &mode{meta}{"<%" ">" "\B" "\B" "\W>" "<" ">"}& 13 | <%include "lib-common.m">& 14 | <%mode pop>& 15 | // 16 | // Usage: &A&_{}B 17 | // 18 | // Null macro 19 | // 20 | &define{_}{$1}& 21 | // vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=perl 22 | -------------------------------------------------------------------------------- /share/lib.json.m: -------------------------------------------------------------------------------- 1 | // 2 | // JSON macros 3 | // 4 | // Included in JSON expansion 5 | // 6 | &mode{push}& 7 | &mode{string}{ccc "&\n" "" ""}& 8 | &mode{string}{ccc "<#" "#>" ""}& 9 | &mode{string}{iqi "'" "'" ""}& 10 | &mode{string}{iQi "\"" "\"" ""}& 11 | &mode{user}{"<%" ">" "\B" "\B" "\W>" "<" ">" "$" ""}& 12 | &mode{meta}{"<%" ">" "\B" "\B" "\W>" "<" ">"}& 13 | <%include "lib-common.m">& 14 | <%mode pop>& 15 | // 16 | // Usage: &A&_{}B 17 | // 18 | // Null macro 19 | // 20 | &define{_}{$1}& 21 | // vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=perl 22 | -------------------------------------------------------------------------------- /tests/expand/mpcss-08.css: -------------------------------------------------------------------------------- 1 | // examples from GPM paper 2 | &define{A}{A$1A}& 3 | &define{B}{B&A{X$1X}B}& 4 | &define{APA}{P$1$1P}& 5 | & 6 | &A{C} 7 | &A{ACA} 8 | &A{&A{C}} 9 | &A{XDX} 10 | &B{D} 11 | &A{P} 12 | &APA{Y} 13 | &call{&A{P}}{Y} 14 | & 15 | &mode{comment}{qqq "[" "]"}& 16 | Q[&A}{C}]R 17 | &A{[&A}{X}]} 18 | &B{[&A}{X}]} 19 | Q[&]R[}] 20 | Q[[&A}{C}]]R 21 | & 22 | /* Output: 23 | ACA 24 | AACAA 25 | AACAA 26 | AXDXA 27 | BAXDXAB 28 | APA 29 | PYYP 30 | PYYP 31 | Q&A C}R 32 | A&A X}A 33 | BAX&A X}XAB 34 | Q&R} 35 | Q[&A C}]R 36 | */& 37 | -------------------------------------------------------------------------------- /share/milligram/blockquote.css: -------------------------------------------------------------------------------- 1 | // Adapted 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 | // Blockquote 11 | // –––––––––––––––––––––––––––––––––––––––––––––––––– 12 | 13 | blockquote { 14 | border-left: 0.3rem solid &ColorQuaternary; 15 | margin-left: 0; 16 | margin-right: 0; 17 | padding: 1rem 1.5rem; 18 | } 19 | 20 | blockquote *:last-child { 21 | margin-bottom: 0; 22 | } 23 | 24 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss 25 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjson-02.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "firstName": "John", 4 | "lastName": "Smith", 5 | "age": 25, 6 | "address": { 7 | "streetAddress": "21 2nd Street", 8 | "city": "New York", 9 | "state": "NY", 10 | "postalCode": "10021" 11 | }, 12 | "phoneNumber": [ 13 | { 14 | "type": "home", 15 | "number": "212 555-1234" 16 | }, 17 | { 18 | "type": "fax", 19 | "number": "646 555-4567" 20 | } 21 | ], 22 | "gender": { 23 | "type": "male" 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /tests/expand/mpjqt-06.jqt: -------------------------------------------------------------------------------- 1 | <# examples from GPM paper #>& 2 | <%define A A$1A>& 3 | <%define B B<%A X$1X>B>& 4 | <%define APA P$1$1P>& 5 | & 6 | <%A C> 7 | <%A ACA> 8 | <%A <%A C>> 9 | <%A XDX> 10 | <%B D> 11 | <%A P> 12 | <%APA Y> 13 | <%call <%A P> Y> 14 | & 15 | <%mode comment qqq "[" "]">& 16 | Q[<%A C>]R 17 | <%A [<%A X>]> 18 | <%B [<%A X>]> 19 | Q[<%]R[>] 20 | Q[[<%A C>]]R 21 | & 22 | <# Output: 23 | ACA 24 | AACAA 25 | AACAA 26 | AXDXA 27 | BAXDXAB 28 | APA 29 | PYYP 30 | PYYP 31 | Q<%A C>R 32 | A<%A X>A 33 | BAX<%A X>XAB 34 | Q<%R> 35 | Q[<%A C>]R 36 | #>& 37 | -------------------------------------------------------------------------------- /tests/expand/mpmd-07.md: -------------------------------------------------------------------------------- 1 | <# examples from GPM paper #>& 2 | <%define A A$1A>& 3 | <%define B B<%A X$1X>B>& 4 | <%define APA P$1$1P>& 5 | & 6 | <%A C> 7 | <%A ACA> 8 | <%A <%A C>> 9 | <%A XDX> 10 | <%B D> 11 | <%A P> 12 | <%APA Y> 13 | <%call <%A P> Y> 14 | & 15 | <%mode comment qqq "[" "]">& 16 | Q[<%A C>]R 17 | <%A [<%A X>]> 18 | <%B [<%A X>]> 19 | Q[<%]R[>] 20 | Q[[<%A C>]]R 21 | & 22 | <# Output: 23 | ACA 24 | AACAA 25 | AACAA 26 | AXDXA 27 | BAXDXAB 28 | APA 29 | PYYP 30 | PYYP 31 | Q<%A C>R 32 | A<%A X>A 33 | BAX<%A X>XAB 34 | Q<%R> 35 | Q[<%A C>]R 36 | #>& 37 | -------------------------------------------------------------------------------- /docs/blocks/menu-bar/markup.html: -------------------------------------------------------------------------------- 1 | <####################################################################### 2 | # Menu Bar 3 | ######################################################################>& 4 | 13 | <# 14 | vim:ts=2:sw=2:ai:et:fileencoding=utf8:syntax=html 15 | #>& 16 | -------------------------------------------------------------------------------- /tests/expand/mpjson-05.json: -------------------------------------------------------------------------------- 1 | /* Macros */ 2 | &define{address}{ 3 | "streetAddress": "21 2nd Street", 4 | "city": "New York", 5 | "state": "NY", 6 | "postalCode": "10021" 7 | } 8 | { 9 | "firstName": "John", 10 | "lastName": "Smith", 11 | "age": 25, 12 | "address": { &address }, 13 | "phoneNumber": [ 14 | { 15 | "type": "home", 16 | "number": "212 555-1234" 17 | }, 18 | { 19 | "type": "fax", 20 | "number": "646 555-4567" 21 | } 22 | ], 23 | "gender": { 24 | "type": "male" 25 | } 26 | } 27 | // vim:sw=4:ts=4:ai:et:syntax=javascript 28 | -------------------------------------------------------------------------------- /tests/format/data/store.yaml: -------------------------------------------------------------------------------- 1 | store: 2 | bicycle: 3 | color: red 4 | price: 19.95 5 | book: 6 | - author: Nigel Rees 7 | category: reference 8 | price: 8.95 9 | title: Sayings of the Century 10 | - author: Evelyn Waugh 11 | category: fiction 12 | price: 12.99 13 | title: Sword of Honour 14 | - author: Herman Melville 15 | category: fiction 16 | isbn: 0-553-21311-3 17 | price: 8.99 18 | title: Moby Dick 19 | - author: J. R. R. Tolkien 20 | category: fiction 21 | isbn: 0-395-19395-8 22 | price: 22.99 23 | title: The Lord of the Rings 24 | -------------------------------------------------------------------------------- /tests/jqt/filters/filters.jq: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # User defined filters 3 | ######################################################################## 4 | 5 | # `iterate` returns an infinite stream of repeated applications of `f` to `.`: 6 | # x | iterate(f) = x, x|f, x|f|f... 7 | def iterate(f): 8 | def R: ., (f | R); 9 | . | R 10 | ; 11 | 12 | # Infinite generator (use with 'limit') 13 | def fibonacci: 14 | {x: -1, y: 1} 15 | | iterate({x: .y, y: (.x+.y)}) 16 | | (.x+.y) 17 | ; 18 | 19 | # vim:ai:sw=4:ts=4:et:syntax=jq 20 | -------------------------------------------------------------------------------- /docs/blocks/panel/style.css: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////// 2 | // Panel 3 | //////////////////////////////////////////////////////////////////////// 4 | 5 | &BEM{#panel} { 6 | border: 0.3rem solid &ColorQuaternary; 7 | border-radius: 0.4rem; 8 | } 9 | 10 | &BEM{#panel}{}{side-right}, 11 | &CHM{#panel}{}{side-right} { 12 | float: right; 13 | margin: 0 0 0 1rem; 14 | } 15 | 16 | /* 17 | &BEM{#panel}{}{side-left}, 18 | &CHM{#panel}{}{side-left} { 19 | float: left; 20 | margin: 0 1rem 0 0; 21 | } 22 | */ 23 | 24 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=css 25 | -------------------------------------------------------------------------------- /share/sake.d/phase1.jq: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # phase1.jq -- Define contents for `$(Meta)/phase2.make`. 3 | # 4 | # jq -r -f phase1.jq 5 | # < $(Meta)/phase1_site.json 6 | # > $(Meta)/phase1.make 7 | 8 | # 9 | # Output makefile 10 | # 11 | "__phase_1 := 1\n", 12 | "Assets := " + .Assets, 13 | "Blocks := " + .Blocks, 14 | "Content := " + .Content, 15 | "Data := " + .Data, 16 | "Root := " + .Root, 17 | "Layouts := " + .Layouts, 18 | "Styles := " + .Styles, 19 | "\n# \u0076im:syntax=make" 20 | 21 | # vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=jq 22 | -------------------------------------------------------------------------------- /tests/expand/mpjson-02.json: -------------------------------------------------------------------------------- 1 | /* 2 | * JSON example 3 | */ 4 | { 5 | "firstName": "John", 6 | "lastName": "Smith", 7 | "age": 25, 8 | "address": { 9 | "streetAddress": "21 2nd Street", 10 | "city": "New York", 11 | "state": "NY", 12 | "postalCode": "10021" 13 | }, 14 | "phoneNumber": [ 15 | { 16 | "type": "home", 17 | "number": "212 555-1234" 18 | }, 19 | { 20 | "type": "fax", 21 | "number": "646 555-4567" 22 | } 23 | ], 24 | "gender": { 25 | "type": "male" 26 | } 27 | } 28 | // vim:sw=4:ts=4:ai:et:syntax=javascript 29 | -------------------------------------------------------------------------------- /docs/content/LINKS.txt: -------------------------------------------------------------------------------- 1 | <# 2 | # Global links 3 | #>& 4 | 5 | [JQT]: https://fadado.github.io/jqt/ 6 | [JQ]: https://stedolan.github.io/jq/ 7 | [REPO]: https://github.com/fadado/jqt 8 | [GPP]: https://logological.org/gpp 9 | [GPPMAN]: https://files.nothingisreal.com/software/gpp/gpp.html 10 | [PANDOC]: http://pandoc.org/ 11 | [BASH]: https://www.gnu.org/software/bash/ 12 | [SED]: https://www.gnu.org/software/sed/ 13 | [MAKE]: https://www.gnu.org/software/make/ 14 | [YAML]: http://yaml.org/ 15 | [JSON]: http://json.org/ 16 | [MARKDOWN]: https://daringfireball.net/projects/markdown/ 17 | 18 | <# 19 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 20 | #>& 21 | -------------------------------------------------------------------------------- /docs/blocks/body/_blog/markup.html: -------------------------------------------------------------------------------- 1 | <####################################################################### 2 | # Body for blog posts 3 | ######################################################################>& 4 |
5 | {% pages[] | select(.Section=="blog") %} 6 |
7 | {{.title}} 8 |

{{.description}} 9 | {{ .updated | fromdate | strftime("%B %Y") }}

10 |
11 | {% end %} 12 |
13 | <# 14 | vim:ts=2:sw=2:ai:et:fileencoding=utf8:syntax=html 15 | #>& 16 | -------------------------------------------------------------------------------- /docs/content/macros.m: -------------------------------------------------------------------------------- 1 | <# 2 | # Extra macros for this site 3 | #>& 4 | <# Quote character, only for this file #>& 5 | <%mode quote "\\">& 6 | <# sc -- small caps style 7 | # Usage: <%sc word> 8 | # <%sc 'text with spaces'> 9 | #>& 10 | <%define sc $1>& 11 | <# cite -- HTML cite element 12 | # Usage: <%cite word> 13 | # <%cite 'text with spaces'> 14 | #>& 15 | <%define cite $1>& 16 | <# dfn -- HTML dfn element 17 | # Usage: <%dfn word> 18 | # <%dfn 'text with spaces'> 19 | #>& 20 | <%define dfn $1>& 21 | <# 22 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=perl 23 | #>& 24 | -------------------------------------------------------------------------------- /tests/jqt/expected/macros-00.txt: -------------------------------------------------------------------------------- 1 | 5 | 6 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjson-07.json: -------------------------------------------------------------------------------- 1 | 2 | 3 | { "husband": 4 | { 5 | "firstName": "John", 6 | "lastName": "Smith", 7 | "age": 25, 8 | "address": {"streetAddress": "21 2nd Street","city": "New York","state": "NY","postalCode": "10021"}, 9 | "gender": { 10 | "type": "male" 11 | } 12 | } 13 | "spouse": 14 | { 15 | "firstName": "Mary", 16 | "lastName": "Smith", 17 | "age": 26, 18 | "address": {"streetAddress": "21 2nd Street","city": "New York","state": "NY","postalCode": "10021"}, 19 | "gender": { 20 | "type": "female" 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /docs/styles/media.css: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////// 2 | // Media 3 | //////////////////////////////////////////////////////////////////////// 4 | 5 | /* Larger than mobile */ 6 | //@media screen and (min-width: 400px) { } 7 | 8 | /* Larger than phablet (also point when grid becomes active) */ 9 | //@media screen and (min-width: 550px) { } 10 | 11 | /* Larger than tablet */ 12 | //@media screen and (min-width: 750px) { } 13 | 14 | /* Larger than desktop */ 15 | //@media screen and (min-width: 1000px) { } 16 | 17 | /* Larger than Desktop HD */ 18 | //@media screen and (min-width: 1200px) { } 19 | 20 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss 21 | -------------------------------------------------------------------------------- /share/sake.d/styles.make: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # styles.make -- Generate main CSS stylesheet. 3 | # 4 | # Exported rules for: 5 | # $(Root)/styles.css 6 | 7 | # JQTLIB defined in `sake` script. 8 | 9 | # Secondary prerequisites. 10 | $(Root)/styles.css: \ 11 | $(JQTLIB)/milligram/*.css \ 12 | $(JQTLIB)/milligram/*.m \ 13 | $(Styles)/*.css \ 14 | $(Blocks)/*/style.css \ 15 | $(Blocks)/*/*/style.css \ 16 | 17 | $(Root)/styles.css: $(Styles)/main.css $(THIS) \ 18 | | $(Root) 19 | $(info ==> $@) 20 | jqt -P CSS-min -I$(JQTLIB) -I$(Styles) < $< > $@ 21 | 22 | build:: $(Root)/styles.css 23 | 24 | # vim:ai:sw=8:ts=8:noet:fileencoding=utf8:syntax=make 25 | -------------------------------------------------------------------------------- /tests/expand/mpjson-06.json: -------------------------------------------------------------------------------- 1 | /* Macros */ 2 | &define{address}{ 3 | "streetAddress": "21 2nd Street", 4 | "city": "New York", 5 | "state": "NY", 6 | "postalCode": "10021" 7 | } 8 | { "husband": 9 | { 10 | "firstName": "John", 11 | "lastName": "Smith", 12 | "age": 25, 13 | "address": { &address }, 14 | "gender": { 15 | "type": "male" 16 | } 17 | } 18 | "spouse": 19 | { 20 | "firstName": "Mary", 21 | "lastName": "Smith", 22 | "age": 26, 23 | "address": { &address }, 24 | "gender": { 25 | "type": "female" 26 | } 27 | } 28 | } 29 | // vim:sw=4:ts=4:ai:et:syntax=javascript 30 | -------------------------------------------------------------------------------- /share/milligram/list.css: -------------------------------------------------------------------------------- 1 | // Adapted 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 | // List 11 | // –––––––––––––––––––––––––––––––––––––––––––––––––– 12 | 13 | &define{_lists}{$1 dl, $1 ol, $1 ul} 14 | 15 | &_lists{} { 16 | list-style: none; 17 | margin-top: 0; 18 | padding-left: 0; 19 | } 20 | 21 | &_lists{dl}, 22 | &_lists{ol}, 23 | &_lists{ul} { 24 | font-size: 90%; 25 | margin: 1.5rem 0 1.5rem 3.0rem; 26 | } 27 | 28 | ol { 29 | list-style: decimal inside; 30 | } 31 | 32 | ul { 33 | list-style: circle inside; 34 | } 35 | 36 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss 37 | -------------------------------------------------------------------------------- /tests/expand/mpjson-07.json: -------------------------------------------------------------------------------- 1 | /* Macros; continuation lines */ 2 | &define{address}{& 3 | "streetAddress": "21 2nd Street",& 4 | "city": "New York",& 5 | "state": "NY",& 6 | "postalCode": "10021"& 7 | } 8 | { "husband": 9 | { 10 | "firstName": "John", 11 | "lastName": "Smith", 12 | "age": 25, 13 | "address": {&address}, 14 | "gender": { 15 | "type": "male" 16 | } 17 | } 18 | "spouse": 19 | { 20 | "firstName": "Mary", 21 | "lastName": "Smith", 22 | "age": 26, 23 | "address": {&address}, 24 | "gender": { 25 | "type": "female" 26 | } 27 | } 28 | } 29 | // vim:sw=4:ts=4:ai:et:syntax=javascript 30 | -------------------------------------------------------------------------------- /tests/jqt/expected/bloc-00.txt: -------------------------------------------------------------------------------- 1 | ======================= 2 | Tests about blocks 3 | ======================= 4 | 5 | The value of pi is 3.141592653589793. 6 | Pi squared: 6.283185307179586 7 | Pi squared: 6.283185307179586 8 | Array [7,6,5,4,3,2,1] has length 7 9 | Array [7,6,5,4,3,2,1] has length 7 10 | 11 | Array $a has value 7 at position 0 12 | Array .array and array $a are equal? (true) 13 | Values sorted as strings: ["10","12","14","2","4","6","8"] 14 | 15 | ----- 16 | I expand! 17 | I expand to 'Neque porro quisquam' 18 | I expand to '3.141592653589793' 19 | I expand preserving $jqt: '3.141592653589793' 20 | ----- 21 | ----- 22 | 23 | I expand to 'Neque porro quisquam' 24 | I expand to 'Neque porro quisquam' 25 | 26 | -------------------------------------------------------------------------------- /share/milligram/utility.css: -------------------------------------------------------------------------------- 1 | // Adapted 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 | // Utility 11 | // –––––––––––––––––––––––––––––––––––––––––––––––––– 12 | 13 | // Clear a float with .%clearfix 14 | // JJOR: prefixed 15 | &SEL{%clearfix}::after { 16 | clear: both; 17 | content: ' '; // The space content is one way to avoid an Opera bug. 18 | display: table; 19 | } 20 | 21 | // Float either direction 22 | // JJOR: prefixed with % 23 | &SEL{%float-right} { 24 | float: right; 25 | } 26 | 27 | &SEL{%float-left} { 28 | float: left; 29 | } 30 | 31 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss 32 | -------------------------------------------------------------------------------- /docs/blocks/toc/style.css: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////// 2 | // Toc 3 | //////////////////////////////////////////////////////////////////////// 4 | 5 | &BEM{toc} { 6 | max-width: 22em; 7 | padding: 0 1em; 8 | text-align: center; 9 | font-size: 80%; 10 | } 11 | 12 | &BEM{toc}{title} { 13 | margin-bottom: 0.5em; 14 | border-bottom: 0.1rem solid &ColorQuaternary; 15 | font-weight: bold; 16 | } 17 | 18 | &BEM{toc} ul { 19 | margin-top: 0; 20 | margin-bottom: 0; 21 | list-style-type: square; 22 | font-size: inherit; 23 | text-align: left; 24 | line-height: 1.4; 25 | } 26 | 27 | &BEM{toc} li { 28 | margin: 0; 29 | } 30 | 31 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=css 32 | -------------------------------------------------------------------------------- /tests/expand/expected/mpjson-06.json: -------------------------------------------------------------------------------- 1 | 2 | 3 | { "husband": 4 | { 5 | "firstName": "John", 6 | "lastName": "Smith", 7 | "age": 25, 8 | "address": { "streetAddress": "21 2nd Street", 9 | "city": "New York", 10 | "state": "NY", 11 | "postalCode": "10021" 12 | }, 13 | "gender": { 14 | "type": "male" 15 | } 16 | } 17 | "spouse": 18 | { 19 | "firstName": "Mary", 20 | "lastName": "Smith", 21 | "age": 26, 22 | "address": { "streetAddress": "21 2nd Street", 23 | "city": "New York", 24 | "state": "NY", 25 | "postalCode": "10021" 26 | }, 27 | "gender": { 28 | "type": "female" 29 | } 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /docs/blocks/repository/markup.html: -------------------------------------------------------------------------------- 1 | <####################################################################### 2 | # Repository 3 | ######################################################################>& 4 |
    5 |
  1. code
  2. 6 |
  3. issues
  4. 7 |
  5. wiki
  6. 8 |
  7. releases
  8. 9 |
  9. top
  10. 10 |
11 | <# 12 | vim:ts=2:sw=2:ai:et:fileencoding=utf8:syntax=html 13 | #>& 14 | -------------------------------------------------------------------------------- /share/sake.d/sitemap.make: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # sitemap.make -- Define rules for site map. 3 | # 4 | # Exported rules for: 5 | # $(Root)/sitemap.xml 6 | # $(Root)/sitemap.xml.gz 7 | 8 | $(Root)/sitemap.xml: $(SCRIPT) $(THIS) 9 | $(Root)/sitemap.xml: $(Meta)/pages-by-id.json $(Meta)/phase1_site.json \ 10 | | $(Root) 11 | $(info ==> $@) 12 | jq --raw-output \ 13 | --slurpfile site $(Meta)/phase1_site.json \ 14 | --from-file $(MDIR)/sitemap.jq \ 15 | < $< > $@ 16 | 17 | $(Root)/sitemap.xml.gz: $(Root)/sitemap.xml 18 | $(info ==> $@) 19 | @gzip --stdout < $< > $@ 20 | 21 | build:: $(Root)/sitemap.xml $(Root)/sitemap.xml.gz 22 | 23 | # vim:ai:sw=8:ts=8:noet:fileencoding=utf8:syntax=make 24 | -------------------------------------------------------------------------------- /share/milligram/code.css: -------------------------------------------------------------------------------- 1 | // Adapted 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 | // Code 11 | // –––––––––––––––––––––––––––––––––––––––––––––––––– 12 | 13 | code { 14 | background: &ColorTertiary; 15 | border-radius: .4rem; 16 | font-size: 86%; 17 | margin: 0 .2rem; 18 | padding: .2rem .5rem; 19 | white-space: nowrap; 20 | } 21 | 22 | pre { 23 | background: &ColorTertiary; 24 | border-left: 0.3rem solid &ColorPrimary; 25 | overflow-y: hidden; 26 | } 27 | 28 | pre > code { 29 | border-radius: 0; 30 | display: block; 31 | padding: 1rem 1.5rem; 32 | white-space: pre; 33 | } 34 | 35 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss 36 | -------------------------------------------------------------------------------- /docs/content/blog/2017-04-13-hello.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: JQT first blog post 3 | description: | 4 | First post in the jqt blog. This section will offer a medium to add 5 | documentation to the JQT site and serve as a test for the build system 6 | used. 7 | keywords: blog, post, jqt, jq, pandoc 8 | published: "2017-04-13T06:45:07Z" 9 | updated: "2017-04-13T06:45:07Z" 10 | --- 11 | <%include content/LINKS.txt>& 12 | 13 | ## First post! 14 | 15 | To explore new aplications for **JQT** this post starts a blog about **JQT**. 16 | 17 | Main technologies behind `jqt` used to build the blog: 18 | 19 | * [`gpp`][GPP] 20 | * [`jq`][JQ] 21 | * [`pandoc`][PANDOC] 22 | 23 | And of course [`make`][MAKE] to organize the build. 24 | 25 | 28 | -------------------------------------------------------------------------------- /docs/blocks/menu-bar/style.css: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////// 2 | // Menu Bar 3 | //////////////////////////////////////////////////////////////////////// 4 | 5 | &BEM{menu-bar} { 6 | display: inline; 7 | padding: 0; 8 | font-variant: small-caps; 9 | text-transform: lowercase; 10 | list-style: none; 11 | } 12 | 13 | &BEM{menu-bar}{item} { 14 | display: inline; 15 | font-size: 120%; 16 | font-weight: bold; 17 | } 18 | 19 | &BEM{menu-bar}{item}:first-child { 20 | margin-left: 1rem; 21 | } 22 | 23 | &BEM{menu-bar}{item}:not(:last-child) { 24 | margin-right: 2rem; 25 | } 26 | 27 | &BEM{menu-bar}{item}{current} > a, 28 | &CHM{menu-bar}{item}{current} > a { 29 | text-decoration: underline; 30 | } 31 | 32 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=css 33 | -------------------------------------------------------------------------------- /share/milligram/color.css: -------------------------------------------------------------------------------- 1 | // Adapted 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 | // Color 11 | // –––––––––––––––––––––––––––––––––––––––––––––––––– 12 | 13 | &ifndef{ColorInitial} 14 | &define{ColorInitial}{#FFFFFF} 15 | &endif 16 | 17 | &ifndef{ColorPrimary} 18 | &define{ColorPrimary}{#9B4DCA} 19 | &endif 20 | 21 | &ifndef{ColorSecondary} 22 | &define{ColorSecondary}{#606C76} 23 | &endif 24 | 25 | &ifndef{ColorTertiary} 26 | &define{ColorTertiary}{#F4F5F6} 27 | &endif 28 | 29 | &ifndef{ColorQuaternary} 30 | &define{ColorQuaternary}{#D1D1D1} 31 | &endif 32 | 33 | &ifndef{ColorQuinary} 34 | &define{ColorQuinary}{#E1E1E1} 35 | &endif 36 | 37 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss 38 | -------------------------------------------------------------------------------- /share/sake.d/phase3_json.jq: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # phase3_json.jq -- Define contents for `$(Meta)/phase3_json.json`. 3 | # 4 | # output from grep/sed includes | 5 | # jq -nR 6 | # -f ./phase3_json.jq 7 | # --arg Layouts $(Layouts) 8 | # > $(Meta)/phase3_json.json 9 | 10 | def branch($root; $tree): 11 | def _branch: 12 | if in($tree) 13 | then . , ($tree[.][] | _branch) 14 | else . 15 | end 16 | ; 17 | [$root | _branch] | sort 18 | ; 19 | 20 | reduce inputs as $line 21 | ({}; ($line/"\t") as [$key,$value] | .[$key]+=[$value]) 22 | | . as $tree 23 | | reduce (keys_unsorted[]|select(startswith($Layouts+"/"))) as $r 24 | ({}; .[$r]=branch($r; $tree)) 25 | 26 | 27 | # vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=jq 28 | -------------------------------------------------------------------------------- /share/sake.d/phase1_site.jq: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # phase1_site.jq -- Define global members using default values. 3 | # 4 | # jq -S -f phase1_site.jq --arg Meta $(Meta) 5 | # < $(Meta)/config.json 6 | # > $(Meta)/phase1_site.json 7 | 8 | # Delete `.defaults` and add some new members with default value if not defined 9 | # in the configuration file. 10 | # 11 | del(.defaults) 12 | + { 13 | Meta: $Meta, 14 | Assets: (.Assets // "assets"), 15 | Blocks: (.Blocks // "blocks"), 16 | Content: (.Content // "content"), 17 | Data: (.Data // "data"), 18 | Root: (.Root // "_site"), 19 | Layouts: (.Layouts // "layouts"), 20 | Styles: (.Styles // "styles") 21 | } 22 | 23 | # vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=jq 24 | -------------------------------------------------------------------------------- /tests/jqt/expected/syntax-00.txt: -------------------------------------------------------------------------------- 1 | ======================= 2 | Syntax tests 3 | ======================= 4 | 5 | _______________________ 6 | Comments 7 | _______________________ 8 | 9 | 1 prefixsuffix 10 | 2 prefix suffix 11 | 3 prefix suffix 12 | 4 prefix suffix 13 | 5 14 | 6 prefixsuffix 15 | 7 prefixsuffix 16 | 8 prefixsuffix 17 | 9 18 | 19 | _______________________ 20 | Expressions 21 | _______________________ 22 | 23 | 2 + 2 = 4 24 | 2 + 2 = 4 25 | 2 + 2 = 4 26 | 27 | _______________________ 28 | One line blocks 29 | _______________________ 30 | 31 | 1 Diga 33 32 | 2 Diga 33 33 | 3 Diga 33 34 | 4 Diga 33 35 | 5 Diga 33 36 | 37 | _______________________ 38 | Raw block 39 | _______________________ 40 | 41 | raw 42 | raw 43 | raw 44 | {{ expression }} 45 | {{ expression }} 46 | {% code %} 47 | {# comment #} 48 | 49 | ======================= 50 | 51 | -------------------------------------------------------------------------------- /bin/csv2json: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Simple CSV to JSON conversor 4 | 5 | import sys 6 | import csv 7 | import json 8 | 9 | def error(e): 10 | sys.stderr.write(type(e).__name__ + ': ' + str(e) + '\n') 11 | sys.exit(1) 12 | 13 | def load_csv(): 14 | if len(sys.argv) > 1: 15 | reader = csv.DictReader(open(sys.argv[1]) ) 16 | else: 17 | reader = csv.DictReader(sys.stdin) 18 | return reader 19 | 20 | def dump_json(seq): 21 | d = None 22 | for d in seq: 23 | json.dump(d, sys.stdout, indent=2, sort_keys=False) 24 | sys.stdout.write('\n') 25 | if d is None: 26 | sys.stdout.write('\n') 27 | 28 | # 29 | # Main 30 | # 31 | 32 | try: 33 | dump_json(load_csv()) 34 | except Exception as e: 35 | error(e) 36 | 37 | sys.exit(0); 38 | 39 | # vim:ai:sw=4:ts=4:et:fileencoding=utf-8:syntax=python 40 | -------------------------------------------------------------------------------- /docs/content/EXAMPLE.txt: -------------------------------------------------------------------------------- 1 | <# 2 | # Template example 3 | #>& 4 | 5 | ``` 6 | 7 | 8 | {{page.title | gsub("<[^>]*>"; "")}} 9 | {# include files in preprocessing stage: #} 10 | <%include "head.html"> 11 | 12 | {# optional line: #} 13 | 14 | {# implicit loop for all authors: #} 15 | {% page.author | sort[] %} 16 | 17 | 18 |

{{page.title}}

19 |
20 | {{$jqt._content}} 21 |
22 | {# macro calls: #} 23 | <%partial analytics 'UA-82432866-1'> 24 | 25 | 26 | ``` 27 | 28 | <# 29 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 30 | #>& 31 | -------------------------------------------------------------------------------- /docs/styles/main.css: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////// 2 | // Top-level stylesheet 3 | //////////////////////////////////////////////////////////////////////// 4 | 5 | @import url("https://fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic"); 6 | 7 | &include{milligram.css} 8 | 9 | &include{blocks/body/_blog/style.css} 10 | &include{blocks/container/style.css} 11 | &include{blocks/header/style.css} 12 | &include{blocks/footer/style.css} 13 | &include{blocks/panel/style.css} 14 | &include{blocks/content/style.css} 15 | &include{blocks/menu-bar/style.css} 16 | &include{blocks/logo/style.css} 17 | &include{blocks/toc/style.css} 18 | &include{blocks/license/style.css} 19 | &include{blocks/repository/style.css} 20 | 21 | // Not used 22 | //&include{media.css} 23 | 24 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss 25 | -------------------------------------------------------------------------------- /tests/format/data/store.json: -------------------------------------------------------------------------------- 1 | { "store": { 2 | "book": [ 3 | { "category": "reference", 4 | "author": "Nigel Rees", 5 | "title": "Sayings of the Century", 6 | "price": 8.95 7 | }, 8 | { "category": "fiction", 9 | "author": "Evelyn Waugh", 10 | "title": "Sword of Honour", 11 | "price": 12.99 12 | }, 13 | { "category": "fiction", 14 | "author": "Herman Melville", 15 | "title": "Moby Dick", 16 | "isbn": "0-553-21311-3", 17 | "price": 8.99 18 | }, 19 | { "category": "fiction", 20 | "author": "J. R. R. Tolkien", 21 | "title": "The Lord of the Rings", 22 | "isbn": "0-395-19395-8", 23 | "price": 22.99 24 | } 25 | ], 26 | "bicycle": { 27 | "color": "red", 28 | "price": 19.95 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /share/sake.d/sitemap.jq: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # sitemap.jq -- Generate site map XML file. 3 | # 4 | # jq -r -f sitemap.jq 5 | # --slurpfile site $(Meta)/phase1_site.json 6 | # < $(Meta)/pages-by-id.json 7 | # > $(Root)/sitemap.xml 8 | 9 | $site[0].baseurl as $baseurl | 10 | 11 | "", 12 | 13 | "", 14 | 15 | (.[] | 16 | "\t", 17 | "\t\t" + $baseurl + "/" + .url + "", 18 | "\t\t" + .updated + "", 19 | "\t" 20 | ), 21 | 22 | "" 23 | 24 | # vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=jq 25 | -------------------------------------------------------------------------------- /bin/yaml2json: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Simple YAML to JSON conversor 4 | 5 | import sys 6 | import yaml 7 | import json 8 | 9 | def error(e): 10 | sys.stderr.write(type(e).__name__ + ': ' + str(e) + '\n') 11 | sys.exit(1) 12 | 13 | def load_yaml(): 14 | if len(sys.argv) > 1: 15 | seq = yaml.safe_load_all(open(sys.argv[1])) 16 | else: 17 | seq = yaml.safe_load_all(sys.stdin) 18 | return seq 19 | 20 | def dump_json(seq): 21 | d = None 22 | for d in seq: 23 | json.dump(d, sys.stdout, indent=2, sort_keys=False) 24 | sys.stdout.write('\n') 25 | if d is None: # some dumped? 26 | sys.stdout.write('\n') 27 | 28 | # 29 | # Main 30 | # 31 | 32 | try: 33 | dump_json(load_yaml()) 34 | except Exception as e: 35 | error(e) 36 | 37 | sys.exit(0); 38 | 39 | # vim:ai:sw=4:ts=4:et:fileencoding=utf-8:syntax=python 40 | -------------------------------------------------------------------------------- /share/milligram/spacing.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 | &ifndef{SpacingScale} 11 | &ifdef{Scale} 12 | &define{SpacingScale}{&Scale} 13 | &else 14 | &define{SpacingScale}{1.0} 15 | &endif 16 | &endif 17 | 18 | // Spacing 19 | // –––––––––––––––––––––––––––––––––––––––––––––––––– 20 | 21 | &BEM{button}, 22 | button, 23 | dd, 24 | dt, 25 | li { 26 | margin-bottom: calc(&SpacingScale * 1.0rem); 27 | } 28 | 29 | fieldset, 30 | input, 31 | select, 32 | textarea { 33 | margin-bottom: calc(&SpacingScale * 1.5rem); 34 | } 35 | 36 | blockquote, 37 | details, // JJOR 38 | dl, 39 | figure, 40 | form, 41 | ol, 42 | p, 43 | pre, 44 | summary, // JJOR 45 | table, 46 | ul { 47 | margin-bottom: calc(&SpacingScale * 2.5rem); 48 | } 49 | 50 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss 51 | -------------------------------------------------------------------------------- /docs/blocks/repository/style.css: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////// 2 | // Repository 3 | //////////////////////////////////////////////////////////////////////// 4 | 5 | &BEM{repository} { 6 | text-align: center; 7 | list-style: none; 8 | } 9 | 10 | &BEM{repository}{section} { 11 | display: inline; 12 | font-variant: small-caps; 13 | font-weight: bold; 14 | } 15 | 16 | &BEM{repository}{section} > a:focus { 17 | color: &ColorPrimary; 18 | } 19 | 20 | &BEM{repository}{section} > a:hover { 21 | color: &ColorSecondary; 22 | } 23 | 24 | &BEM{repository}{section}:first-child:before { 25 | content: "❲ "; 26 | color: &ColorSecondary; 27 | } 28 | 29 | &BEM{repository}{section}:not(last-child):after { 30 | content: " ❘ "; 31 | color: &ColorSecondary; 32 | } 33 | 34 | &BEM{repository}{section}:last-child:after { 35 | content: " ❳"; 36 | color: &ColorSecondary; 37 | } 38 | 39 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=css 40 | -------------------------------------------------------------------------------- /bin/yaml2csv: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Simple YAML to CSV conversor 4 | 5 | import sys 6 | import yaml 7 | import csv 8 | 9 | def error(e): 10 | sys.stderr.write(type(e).__name__ + ': ' + str(e) + '\n') 11 | sys.exit(1) 12 | 13 | def load_yaml(): 14 | if len(sys.argv) > 1: 15 | seq = yaml.safe_load_all(open(sys.argv[1])) 16 | else: 17 | seq = yaml.safe_load_all(sys.stdin) 18 | return seq 19 | 20 | def dump_csv(seq): 21 | try: 22 | d = next(seq) 23 | except StopIteration: 24 | sys.stdout.write('\n') 25 | return 26 | writer = csv.DictWriter(sys.stdout, 27 | fieldnames=d.keys(), 28 | quoting=csv.QUOTE_NONNUMERIC) 29 | writer.writeheader() 30 | writer.writerow(d) 31 | for d in seq: 32 | writer.writerow(d) 33 | 34 | # 35 | # Main 36 | # 37 | 38 | try: 39 | dump_csv(load_yaml()) 40 | except Exception as e: 41 | error(e) 42 | 43 | sys.exit(0); 44 | 45 | # vim:ai:sw=4:ts=4:et:fileencoding=utf-8:syntax=python 46 | -------------------------------------------------------------------------------- /share/milligram/base.css: -------------------------------------------------------------------------------- 1 | // Adapted 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 | // Base 11 | // –––––––––––––––––––––––––––––––––––––––––––––––––– 12 | 13 | // Set box-sizing globally to handle padding and border widths 14 | *, 15 | *::after, // JJOR: use :: for pseudo-elements 16 | *::before { 17 | box-sizing: inherit; 18 | } 19 | 20 | // The base font-size is set at 62.5% for having the convenience 21 | // of sizing rems in a way that is similar to using px: 1.6rem = 16px 22 | html { 23 | box-sizing: border-box; 24 | font-size: 62.5%; 25 | } 26 | 27 | // Default body styles 28 | body { 29 | color: &ColorSecondary; 30 | font-family: 'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif; 31 | font-size: 1.6em; // Currently ems cause chrome bug misinterpreting rems on body element 32 | font-weight: 300; 33 | letter-spacing: .01em; 34 | line-height: 1.6; 35 | } 36 | 37 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss 38 | -------------------------------------------------------------------------------- /tests/jqt/cond-00.jqt: -------------------------------------------------------------------------------- 1 | ======================= 2 | Conditional blocks 3 | ======================= 4 | 5 | _____ 6 | {% .yes//empty %} 7 | I expand! 8 | {% end %} 9 | {% .string//empty %} 10 | I expand to '{{.}}' 11 | {% end %} 12 | {% .number//empty %} 13 | I expand to '{{.}}' 14 | {%end%} 15 | {% .number//empty | $jqt %} 16 | I expand preserving $jqt: '{{$jqt.number}}' 17 | {% end %} 18 | _____ 19 | {% .not//empty %} 20 | I vanish! 21 | {% end %} 22 | {% .nil//empty %} 23 | I vanish! 24 | {% end %} 25 | _____ 26 | 27 | {% .yes//empty | $jqt %} 28 | {% .string//empty %}I expand to '{{.}}' 29 | {% end %} 30 | {% .yes//empty | $jqt %} 31 | {% .string//empty %} 32 | I expand to '{{.}}' 33 | {% end %} 34 | {% end %} 35 | 36 | {% (.number > 4)//empty %} 37 | then not 38 | {% end %} 39 | {% (.number < 3 | not)//empty %} 40 | else yes 41 | {% end %} 42 | 43 | {% (.number < 1)//empty %} 44 | case 1 45 | {% end %} 46 | {% (.number < 1 | not)//empty | $jqt %} 47 | {% (.number < 2)//empty %} 48 | case 2 49 | {% end %} 50 | {% (.number < 2 | not)//empty %} 51 | case else 52 | {% end %} 53 | {% end %} 54 | -------------------------------------------------------------------------------- /bin/csv2yaml: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Simple CSV to YAML conversor 4 | 5 | import sys 6 | import csv 7 | import yaml 8 | 9 | def error(e): 10 | sys.stderr.write(type(e).__name__ + ': ' + str(e) + '\n') 11 | sys.exit(1) 12 | 13 | def load_csv(): 14 | if len(sys.argv) > 1: 15 | reader = csv.DictReader(open(sys.argv[1]) ) 16 | else: 17 | reader = csv.DictReader(sys.stdin) 18 | return reader 19 | 20 | def dump_yaml(seq): 21 | d = None 22 | for d in seq: 23 | yaml.safe_dump(d, sys.stdout, 24 | default_flow_style=False, 25 | default_style=None, 26 | encoding='utf-8', 27 | explicit_start=True, 28 | explicit_end=False, 29 | indent=2, 30 | ) 31 | if d is None: # some dumped? 32 | sys.stdout.write('\n') 33 | else: 34 | sys.stdout.write('...\n') 35 | 36 | # 37 | # Main 38 | # 39 | 40 | try: 41 | dump_yaml(load_csv()) 42 | except Exception as e: 43 | error(e) 44 | 45 | sys.exit(0); 46 | 47 | # vim:ai:sw=4:ts=4:et:fileencoding=utf-8:syntax=python 48 | -------------------------------------------------------------------------------- /share/sake.d/tools.make: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # tools.make 3 | # 4 | # Miscelaneous tools. 5 | # 6 | # Imported variables: 7 | # VNU 8 | # Root 9 | # Defined targets: 10 | # print-% 11 | # h5.lint 12 | # h5.valid 13 | 14 | ######################################################################## 15 | # Debug utilities. 16 | ######################################################################## 17 | 18 | # Print any variable value 19 | print-%: ; @echo $* = $($*) 20 | 21 | ######################################################################## 22 | # HTML 5 validation. 23 | ######################################################################## 24 | 25 | # Download vnu.jar from `https://github.com/validator/validator/releases`. 26 | 27 | .PHONY: h5.valid h5.lint 28 | 29 | # Validation tool. 30 | VNU ?= java -jar /usr/local/vnu/vnu.jar 31 | 32 | # Validation. 33 | h5.valid: build 34 | @xmlwf $(Root)/*.html $(Root)/*/*.html 35 | @$(VNU) --errors-only --format gnu $(Root)/*.html 36 | 37 | # Validation with warnings. 38 | h5.lint: build 39 | @xmlwf $(Root)/*.html $(Root)/*/*.html 40 | @$(VNU) --format text $(Root)/*.html 41 | 42 | # vim:ai:sw=8:ts=8:noet:fileencoding=utf8:syntax=make 43 | -------------------------------------------------------------------------------- /share/sake.d/phase3d.jq: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # phase3d.jq -- Define contents for `$(Meta)/phase3d.make`. 3 | # 4 | #?# jq -r -f phase3.jq 5 | #?# --arg Layouts $(Layouts) 6 | #?# --arg Root $(Root) 7 | #?# --slurpfile ldep $(Meta)/phase3_json.json 8 | #?# < $(Meta)/pages-by-id.json 9 | #?# > $(Meta)/phase3d.make 10 | 11 | #_site/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 12 | #_site/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 13 | def page_layouts: 14 | .[] 15 | | "\($Layouts)/\(.Layout).html" as $l 16 | | $Root+"/"+.URL+": " + ($ldep[0][$l] | join(" ")) 17 | ; 18 | 19 | # 20 | # Output makefile 21 | # 22 | 23 | page_layouts, 24 | "\n# \u0076im:syntax=make" 25 | 26 | # vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=jq 27 | -------------------------------------------------------------------------------- /bin/json2yaml: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Simple JSON to YAML conversor 4 | 5 | import sys 6 | import yaml 7 | import json 8 | 9 | def error(e): 10 | sys.stderr.write(type(e).__name__ + ': ' + str(e) + '\n') 11 | sys.exit(1) 12 | 13 | def load_json(): 14 | if len(sys.argv) > 1: 15 | data = open(sys.argv[1]).read().strip() 16 | else: 17 | data = sys.stdin.read().strip() 18 | decoder = json.JSONDecoder(encoding="utf-8", strict=True) 19 | while data != "": 20 | obj, end = decoder.raw_decode(data) 21 | yield obj 22 | data = data[end:].strip() 23 | 24 | def dump_yaml(seq): 25 | obj = None 26 | for obj in seq: 27 | yaml.safe_dump(obj, sys.stdout, 28 | default_flow_style=False, 29 | default_style=None, 30 | encoding='utf-8', 31 | explicit_start=True, 32 | explicit_end=False, 33 | indent=2, 34 | ) 35 | if obj is None: # some dumped? 36 | sys.stdout.write('\n') 37 | else: 38 | sys.stdout.write('...\n') 39 | 40 | # 41 | # Main 42 | # 43 | 44 | try: 45 | dump_yaml(load_json()) 46 | except Exception as e: 47 | error(e) 48 | 49 | sys.exit(0); 50 | 51 | # vim:ai:sw=4:ts=4:et:fileencoding=utf-8:syntax=python 52 | -------------------------------------------------------------------------------- /docs/styles/milligram.css: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////// 2 | // Milligram theme 3 | //////////////////////////////////////////////////////////////////////// 4 | 5 | // Include first! 6 | &include{milligram/BEM.m} 7 | &include{milligram/COLORNAMES.m} 8 | 9 | &include{milligram/Normalize.css} 10 | 11 | // Parameters 12 | &define{ColorInitial}{&White} 13 | &define{ColorPrimary}{&DarkCyan} 14 | &define{ColorSecondary}{&Black} 15 | &define{ColorTertiary}{&Lavender} 16 | &define{ColorQuaternary}{&LightGrey} 17 | 18 | &define{Scale}{1} 19 | &define{SpacingScale}{0.7} 20 | &define{TypographyScale}{0.8} 21 | 22 | @media screen { 23 | html { 24 | background-color: &ColorInitial; 25 | } 26 | } 27 | 28 | // Modules 29 | &include{milligram/color.css} 30 | &include{milligram/base.css} 31 | &include{milligram/spacing.css} 32 | &include{milligram/typography.css} 33 | &include{milligram/blockquote.css} 34 | &include{milligram/code.css} 35 | &include{milligram/link.css} 36 | &include{milligram/list.css} 37 | &include{milligram/table.css} 38 | &include{milligram/divider.css} 39 | &include{milligram/grid.css} 40 | &include{milligram/utility.css} 41 | //&include{milligram/image.css} 42 | //&include{milligram/form.css} 43 | //&include{milligram/button.css} 44 | 45 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | jqt is copyright (c) 2016 Joan Josep Ordinas Rosa 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | 21 | 22 | jqt's documentation (everything found under the docs/ subdirectory in 23 | the source tree) is licensed under the Creative Commons CC BY 3.0 24 | license, which can be found at: 25 | 26 | https://creativecommons.org/licenses/by/3.0/ 27 | -------------------------------------------------------------------------------- /tests/jqt/syntax-00.jqt: -------------------------------------------------------------------------------- 1 | ======================= 2 | Syntax tests 3 | ======================= 4 | 5 | _______________________ 6 | Comments 7 | _______________________ 8 | 9 | 1 prefix{# comment #}suffix 10 | 2 prefix {# comment #} suffix 11 | 3 prefix {# comment #} suffix{# comment #} 12 | 4 {# comment #}prefix {# comment #} suffix{# comment #} 13 | 5 {# MULTI 14 | LINE #} 15 | 6 prefix{# MULTI 16 | LINE #}suffix 17 | 7 prefix{# MULTI 18 | LINE #}suffix{# comment #} 19 | 8 {# comment #}prefix{# MULTI 20 | LINE #}suffix{# comment #} 21 | 9 {# 22 | {{ x }} 23 | {% b %} 24 | {% b %}xxxxxxxxxxxx 25 | {% end %} 26 | {{ 27 | x 28 | x 29 | }} 30 | #} 31 | 32 | _______________________ 33 | Expressions 34 | _______________________ 35 | 36 | 2 + 2 = {{ 2+2 }} 37 | 2 + 2 = {{ 2 38 | + 39 | 2 }} 40 | {{ 2 41 | }} + {{ 2 42 | }} = 4 43 | 44 | _______________________ 45 | One line blocks 46 | _______________________ 47 | 48 | {% 33 %}1 Diga {{.}} 49 | {% 33 %}2 Diga {{ 50 | . 51 | }} 52 | {% 33 %}3 Diga {{ 53 | .+1-1 54 | }} 55 | {% 33 %}4 Di{{"ga"}} {{ 56 | .+1-1 57 | }} 58 | {% 33 %}5 Di{{"ga"+""}} {{ 59 | .-30 60 | }}3 61 | 62 | _______________________ 63 | Raw block 64 | _______________________ 65 | 66 | {% raw %} 67 | raw 68 | {%endraw%} 69 | {% raw %} 70 | raw 71 | {%endraw%} 72 | {% raw %} 73 | raw 74 | {%endraw%} 75 | {% raw %} 76 | {{ expression }} 77 | {%endraw%} 78 | {% raw %} 79 | {{ expression }} 80 | {%endraw%} 81 | {%raw%} 82 | {% code %} 83 | {# comment #} 84 | {%endraw%} 85 | 86 | ======================= 87 | -------------------------------------------------------------------------------- /docs/content/FLOW.txt: -------------------------------------------------------------------------------- 1 | <# 2 | # Flow diagram 3 | #>& 4 | 5 |
6 |
jqt workflow
7 | ``` 8 | jqt +------+ +-------+ jq script 9 | Template +----------->|expand|-->|convert|-------------------------------+ 10 | +------+ +-------+ | 11 | HTML and CSS | 12 | fragments v 13 | MarkDown +------+ +------+ /-------->+-----+ JSON +------+ HTML 14 | Document +----------->|expand|-->|markup|--+ |merge|-------->|render|------> Page 15 | +------+ +------+ \-------->+-----+ +------+ 16 | YAML ^ ^ 17 | metadata | | 18 | JSON +------+ | | 19 | +----------->|expand|-------------------------+ | 20 | Data YAML +------+ | CSS +------+ 21 | +-------------------------------------------------+ +---->|expand|------> Style 22 | YAML snippets +------+ | +------+ 23 | +---------------------->|markup|------------------+ 24 | +------+ 25 | ``` 26 |
27 | 28 | <# 29 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 30 | #>& 31 | -------------------------------------------------------------------------------- /share/milligram/table.css: -------------------------------------------------------------------------------- 1 | // Adapted 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 | // Table 11 | // –––––––––––––––––––––––––––––––––––––––––––––––––– 12 | 13 | table { 14 | border-spacing: 0; 15 | width: 100%; 16 | } 17 | 18 | &define{_cells}{th$1, td$1} 19 | 20 | &_cells{} { 21 | border-bottom: .1rem solid &ColorQuinary; 22 | padding: 1.2rem 1.5rem; 23 | text-align: left; 24 | } 25 | 26 | &_cells{:first-child} { 27 | padding-left: 0; 28 | } 29 | 30 | &_cells{:last-child} { 31 | padding-right: 0; 32 | } 33 | 34 | //@media screen and (max-width: 40rem) { 35 | //} 36 | 37 | /* TODO: import? 38 | @media screen and (max-width: 40.0rem) 39 | table 40 | border-spacing: 0 41 | display: flex 42 | width: 100% 43 | 44 | thead 45 | border-right: solid .1rem $color-quinary 46 | 47 | td, 48 | th 49 | padding-left: 0 50 | 51 | &:first-child 52 | padding-left: 0 53 | 54 | &:last-child 55 | padding-right: 1.2rem 56 | 57 | tbody 58 | display: flex 59 | overflow-x: auto 60 | white-space: nowrap 61 | 62 | tr 63 | border-right: solid .1rem $color-quinary 64 | 65 | &:last-child 66 | border-right: none 67 | 68 | td, 69 | th 70 | display: block 71 | 72 | &:first-child 73 | padding-left: 1.2rem 74 | 75 | &:last-child 76 | padding-right: 1.2rem 77 | */ 78 | 79 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss 80 | -------------------------------------------------------------------------------- /share/milligram/BEM.m: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////// 2 | // BEM macros 3 | //////////////////////////////////////////////////////////////////////// 4 | 5 | // Simple selector 6 | // 7 | // Prefix selector with the escape character \ if necessary. Do not change 8 | // selectors if they start with [A-Za-z_-]. 9 | // 10 | &define{SEL}{.&if{$1 =~ [A-Za-z_-]*}$1&else\$1&endif} 11 | 12 | // Block, element, modifier 13 | // 14 | // Cases: 15 | // 16 | // &BEM{block} => .block 17 | // &BEM{block}{}{modifier} => .block_modifier 18 | // &BEM{block}{element} => .block__element 19 | // &BEM{block}{element}{modifier} => .block__element_modifier 20 | // 21 | &define{BEM}{&SEL{$1}&ifneq{$2}{}__$2&endif&ifneq{$3}{}_$3&endif} 22 | 23 | // Chained modifier 24 | // 25 | // Cases: 26 | // 27 | // &CHM{block}{}{modifier} => .block.-modifier 28 | // &CHM{block}{element}{modifier} => .block__element.-modifier 29 | // 30 | &define{CHM}{&SEL{$1}&ifneq{$2}{}__$2&endif.-$3} 31 | 32 | // Hack 33 | // 34 | // Prefix selector with underline character and protect name with the escape 35 | // character \ if necessary. 36 | // 37 | // ._N 38 | // 39 | &define{HACK}{._&if{$1 =~ [A-Za-z_-]*}$1&else\$1&endif} 40 | 41 | // Naming conventions: 42 | // component, block, module &BEM &CHM 43 | // #object, #layout &BEM &CHM 44 | // %utility &SEL 45 | // $scope &SEL 46 | // ^theme &SEL 47 | // _hack &HACK 48 | 49 | // vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=scss 50 | -------------------------------------------------------------------------------- /docs/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # 3 | # jqt documentation site configuration 4 | # 5 | # Provide defaults to each MarkDown file including `config.yaml`, and is 6 | # available in the `.site` top-level variable. 7 | # 8 | 9 | # ====================================================================== 10 | # Site variables with default values. Can be redefined in this file. 11 | # ====================================================================== 12 | # 13 | # Assets assets 14 | # Blocks blocks 15 | # Content content 16 | # Data data 17 | # Root _site 18 | # Layouts layouts 19 | # Styles styles 20 | 21 | # Changes from defaults (fast RAM disk) 22 | Root: /tmp/jqt 23 | 24 | # 25 | # Site parameters 26 | # 27 | 28 | title: jqt, the jq template engine 29 | title_prefix: jqt 30 | title_delimiter: "·" 31 | baseurl: https://fadado.github.com/jqt/ 32 | lang: &lang en 33 | logo: "❴❴❏❵❵" 34 | 35 | author: &author 36 | - email: jordinas@gmail.com 37 | name: Joan Josep Ordinas Rosa 38 | menu: 39 | - index 40 | - engine 41 | - structure 42 | - content 43 | - data 44 | # - blog/index 45 | 46 | # Default values 47 | defaults: 48 | - idprefix: "" # all files 49 | properties: 50 | author: *author 51 | lang: *lang 52 | Layout: page-toc 53 | Datasets: 54 | - snippets.md 55 | Dependencies: 56 | - content/macros.m 57 | - content/LINKS.txt 58 | # Flags: 59 | # - -mXYZ:$(Meta)/XYZ.json 60 | - idprefix: "blog/" 61 | properties: 62 | Layout: page 63 | 64 | # vim:ts=2:sw=2:ai:et:fileencoding=utf8:syntax=yaml 65 | ... 66 | -------------------------------------------------------------------------------- /docs/layouts/default.html: -------------------------------------------------------------------------------- 1 | <# Top-level page markup #>& 2 | 3 | 4 | 5 | 6 | <# 7 | # Meta elements 8 | #> 9 | 10 | <# Document title and related metadata #> 11 | {{site.title_prefix}} {{site.title_delimiter}} {{page.title}} 12 | 13 | 14 | 15 | <# More metadata #> 16 | 17 | 18 | <# Presentation #> 19 | 20 | 21 | 22 | {{$jqt._highlight}} 23 | 24 | <# 25 | # Document body 26 | #> 27 | 28 | <%include blocks/header/markup.html>& 29 | <%ifdef BODY_BLOCK>& 30 | <%call BODY_BLOCK> 31 | <%else>& 32 | <%error Descendent layout must define BODY_BLOCK macro> 33 | <%endif>& 34 | <%include blocks/footer/markup.html>& 35 | <%partial analytics 'UA-82432866-1'>& 36 | 37 | 38 | <# 39 | vim:ts=2:sw=2:ai:et:fileencoding=utf8:syntax=html 40 | #> 41 | -------------------------------------------------------------------------------- /share/lib-common.m: -------------------------------------------------------------------------------- 1 | <# 2 | # JQT macros 3 | # 4 | # Included in template and document expansion 5 | #>& 6 | <# Quote character, only for this file #>& 7 | <%mode quote "\\">& 8 | <# 9 | # Usage: <%partial name arg...> 10 | # 11 | # Like include but passing (up to 8) parameters to the included file. 12 | # Assume 'm' filename extension. 13 | #>& 14 | <%define partial 15 | <%defeval _partial 16 | <\%defeval _partial 17 | <\%include "$1.m"> 18 | > 19 | ><%_partial><%_partial "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9"><%undef _partial> 20 | >& 21 | <# 22 | # Usage: <%shortcode name>... <%name arg...> 23 | # 24 | # Define name as a macro with contents of name.m as a body. 25 | # Assume 'm' filename extension. 26 | # Equivalent to: <%defeval name <%include name.m>> 27 | #>& 28 | <%define shortcode 29 | <%defeval _shortcode 30 | <\%defeval $1 31 | <\%include "$1.m"> 32 | > 33 | ><%_shortcode><%undef _shortcode> 34 | >& 35 | <# 36 | # Usage: <%scan text> 37 | # 38 | # Evaluate text with macro calls. 39 | #>& 40 | <%define scan 41 | <%defeval _scan $1><%_scan><%undef _scan> 42 | >& 43 | <# 44 | # Usage: <%call name arg...> 45 | # 46 | # Call a macro by name. 47 | #>& 48 | <%define call 49 | <%defeval _call 50 | <\%$1 "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9"> 51 | ><%_call><%undef _call> 52 | >& 53 | <# 54 | # Usage: <%append name text> 55 | # 56 | # Equivalent to: <%defeval name <%name>text.> 57 | #>& 58 | <%define append 59 | <%defeval _append 60 | <\%defeval $1 <%call $1>$2> 61 | ><%_append><%undef _append> 62 | >& 63 | <# 64 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=perl 65 | #>& 66 | -------------------------------------------------------------------------------- /share/analytics.m: -------------------------------------------------------------------------------- 1 | <# 2 | # Usage: <%partial analytics UA-82432866-1> 3 | # 4 | # $1: analytics UA 5 | #>& 6 | 14 | <# OLD VERSION 15 | 28 | #>& 29 | <# LAST VERSION 30 | 40 | #>& 41 | <# 42 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=html 43 | #>& 44 | -------------------------------------------------------------------------------- /share/milligram/typography.css: -------------------------------------------------------------------------------- 1 | // Adapted 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 | &ifndef{TypographyScale} 11 | &ifdef{Scale} 12 | &define{TypographyScale}{&Scale} 13 | &else 14 | &define{TypographyScale}{1.0} 15 | &endif 16 | &endif 17 | 18 | // Typography 19 | // –––––––––––––––––––––––––––––––––––––––––––––––––– 20 | 21 | b, strong { 22 | font-weight: bold; 23 | } 24 | 25 | p { 26 | margin-top: 0; 27 | } 28 | 29 | h1, 30 | h2, 31 | h3, 32 | h4, 33 | h5, 34 | h6 { 35 | font-weight: 300; 36 | letter-spacing: -.1rem; // JJOR: set again in _heading 37 | margin-bottom: calc(&TypographyScale * 2.0rem); 38 | margin-top: 0; // calc(&TypographyScale * 0) 39 | } 40 | 41 | &define{_heading}{ 42 | $1 { 43 | font-size: calc(&TypographyScale * $2); 44 | letter-spacing: $3; 45 | line-height: $4; 46 | } 47 | } 48 | 49 | &_heading{h1}{4.6rem}{-0.1rem}{ 1.2} 50 | &_heading{h2}{3.6rem}{-0.1rem}{ 1.25} 51 | &_heading{h3}{2.8rem}{-0.1rem}{ 1.3} 52 | &_heading{h4}{2.2rem}{-0.08rem}{1.35} 53 | &_heading{h5}{1.8rem}{-0.5rem}{ 1.5} 54 | &_heading{h6}{1.6rem}{ 0.0rem}{ 1.4} 55 | 56 | /* JJOR: Moved? Deleted? 57 | // Larger than mobile screen 58 | @media (min-width: 40rem) { // Safari desktop has a bug using `rem`, but Safari mobile works 59 | h1 { font-size: calc(&TypographyScale * 5.0rem); } 60 | h2 { font-size: calc(&TypographyScale * 4.2rem); } 61 | h3 { font-size: calc(&TypographyScale * 3.6rem); } 62 | h4 { font-size: calc(&TypographyScale * 3.0rem); } 63 | h5 { font-size: calc(&TypographyScale * 2.4rem); } 64 | h6 { font-size: calc(&TypographyScale * 1.5rem); } 65 | } 66 | */ 67 | 68 | // JJOR 69 | q { quotes: "“" "”" "‘" "’"; } 70 | 71 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss 72 | -------------------------------------------------------------------------------- /tests/format/data/au.csv: -------------------------------------------------------------------------------- 1 | "first_name","last_name","company_name","address","city","state","post","phone1","phone2","email","web" 2 | "Ena","Desjardiws","Selsor, Robert J Esq","60562 Ky Rt 321","Bendick Murrell","NS",2803,"02-5226-9402","0415-961-606","ena_desjardiws@desjardiws.com.au","http://www.selsorrobertjesq.com.au" 3 | "Gerardo","Woodka","Morris Downing & Sherred","69206 Jackson Ave","Talmalmo","NS",2640,"02-6044-4682","0443-795-912","gerardo_woodka@hotmail.com","http://www.morrisdowningsherred.com.au" 4 | "Idella","Scotland","Artesian Ice & Cold Storage Co","373 Lafayette St","Cartmeticup","WA",6316,"08-7868-1355","0451-966-921","idella@hotmail.com","http://www.artesianicecoldstorageco.com.au" 5 | "Mariko","Stayer","Inabinet, Macre Esq","534 Schoenborn St #51","Hamel","WA",6215,"08-5558-9019","0427-885-282","mariko_stayer@hotmail.com","http://www.inabinetmacreesq.com.au" 6 | "Mayra","Bena","Buelt, David L Esq","808 Glen Cove Ave","Lane Cove","NS",1595,"02-1455-6085","0453-666-885","mayra.bena@gmail.com","http://www.bueltdavidlesq.com.au" 7 | "Rebbecca","Didio","Brandt, Jonathan F Esq","171 E 24th St","Leith","TA",7315,"03-8174-9123","0458-665-290","rebbecca.didio@didio.com.au","http://www.brandtjonathanfesq.com.au" 8 | "Sherill","Klar","Midway Hotel","87 Sylvan Ave","Nyamup","WA",6258,"08-6522-8931","0427-991-688","sklar@hotmail.com","http://www.midwayhotel.com.au" 9 | "Stevie","Hallo","Landrum Temporary Services","22222 Acoma St","Proston","QL",4613,"07-9997-3366","0497-622-620","stevie.hallo@hotmail.com","http://www.landrumtemporaryservices.com.au" 10 | "Theron","Jarding","Prentiss, Paul F Esq","8839 Ventura Blvd","Blanchetown","SA",5357,"08-6890-4661","0461-862-457","tjarding@hotmail.com","http://www.prentisspaulfesq.com.au" 11 | "Vince","Siena","Vincent J Petti & Co","70 S 18th Pl","Purrawunda","QL",4356,"07-3184-9989","0411-732-965","vince_siena@yahoo.com","http://www.vincentjpettico.com.au" 12 | -------------------------------------------------------------------------------- /docs/blocks/content/style.css: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////// 2 | // Content 3 | //////////////////////////////////////////////////////////////////////// 4 | 5 | &SEL{$content} h2:target::after, 6 | &SEL{$content} h3:target::after, 7 | &SEL{$content} h4:target::after { 8 | content: " §"; 9 | color: &ColorQuaternary; 10 | font-family: serif; 11 | } 12 | 13 | &SEL{$content} td { 14 | font-size: 90%; 15 | padding: 0.8rem 1.0rem; 16 | } 17 | 18 | &SEL{$content} caption { 19 | border-top: .1rem solid &ColorQuinary; 20 | border-bottom: .1rem solid &ColorQuinary; 21 | font-weight: bold; 22 | } 23 | 24 | &SEL{$content} dt { 25 | font-weight: bold; 26 | margin-bottom: 0.1em; 27 | } 28 | 29 | &SEL{$content} ul { 30 | list-style-type: square; 31 | } 32 | 33 | &SEL{$content} pre { 34 | border-radius: 0.4rem; 35 | font-family: "Liberation Mono", "Nimbus Mono L", monospace; 36 | } 37 | 38 | &SEL{$content} cite { 39 | font-style: italic; 40 | } 41 | 42 | &SEL{$content} .footnotes ol { 43 | list-style-type: decimal; 44 | list-style-position: outside; 45 | line-height: 1.3; 46 | font-size: 90%; 47 | margin-left: 1.1em; 48 | } 49 | 50 | &SEL{$content} .footnotes p { 51 | margin: 0; 52 | padding: 0; 53 | } 54 | 55 | &SEL{$content} summary { 56 | cursor: zoom-in; 57 | outline: none; 58 | } 59 | 60 | &SEL{$content} details[open] > summary { 61 | cursor: zoom-out; 62 | } 63 | 64 | &SEL{$content} figure > pre { 65 | border: 0.3rem solid &ColorQuinary; 66 | border-radius: 1rem; 67 | font-size: 1.4rem; 68 | } 69 | 70 | &SEL{$content} &SEL{page-quote} { 71 | float: right; 72 | margin: 0 0 0 auto; 73 | padding-top: 0; 74 | padding-bottom: 0; 75 | max-width: 20em; 76 | font-family: "Liberation Serif", "Times New Roman", Times, serif; 77 | text-align: right; 78 | } 79 | 80 | @media print { 81 | &SEL{$content} figure > pre { 82 | font-size: 1.2rem; 83 | } 84 | } 85 | 86 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=css 87 | -------------------------------------------------------------------------------- /share/sake.d/phase1.make: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # phase1.make -- Rules for files derived from user defined configuration. 3 | # 4 | # Variables defined in $(Meta)/phase1.make: 5 | # __phase_1 6 | # Assets 7 | # Blocks 8 | # Content 9 | # Data 10 | # Root 11 | # Layouts 12 | # Styles 13 | # 14 | # Rules defined in $(MDIR)/phase1.make: 15 | # $(Meta)/config.json 16 | # $(Meta)/phase1_site.json 17 | # $(Meta)/phase1.make 18 | 19 | SUPER := $(MDIR)/main.make 20 | 21 | ######################################################################## 22 | # Files derived from user defined configuration file. 23 | ######################################################################## 24 | 25 | # 26 | # Create `$(Meta)/phase1.make` from `$(Meta)/phase1_site.json` using 27 | # `$(MDIR)/phase1.jq`. 28 | # 29 | $(Meta)/phase1.make: $(SUPER) $(THIS) $(CURDIR)/Sakefile 30 | $(Meta)/phase1.make: $(Meta)/phase1_site.json $(SCRIPT) 31 | $(info ==> $@) 32 | jq --raw-output \ 33 | --from-file $(MDIR)/phase1.jq \ 34 | < $< > $@ 35 | 36 | # 37 | # Create `$(Meta)/phase1_site.json` from `$(Meta)/config.json` using 38 | # `$(MDIR)/phase1_site.jq`. 39 | # 40 | $(Meta)/phase1_site.json: $(Meta)/config.json $(SCRIPT) $(THIS) 41 | $(info ==> $@) 42 | jq --sort-keys \ 43 | --from-file $(MDIR)/phase1_site.jq \ 44 | --arg Meta $(Meta) \ 45 | < $< > $@ 46 | 47 | # 48 | # Create `$(Meta)/config.json` from `config.yaml` or `config.json`. 49 | # 50 | ifeq (config.yaml,$(wildcard config.yaml)) 51 | 52 | # Convert `config.yaml` to `$(Meta)/config.json`. 53 | $(Meta)/config.json: $(CURDIR)/config.yaml $(THIS) \ 54 | | $(Meta) 55 | $(info ==> $@) 56 | yaml2json < $< > $@ 57 | 58 | else ifeq (config.json,$(wildcard config.json)) 59 | 60 | # Convert `config.json` to `$(Meta)/config.json`. 61 | $(Meta)/config.json: $(CURDIR)/config.json $(THIS) \ 62 | | $(Meta) 63 | $(info ==> $@) 64 | jqt -Pjson < $< > $@ 65 | 66 | else 67 | $(error Configuration file not found) 68 | endif 69 | 70 | # vim:ai:sw=8:ts=8:noet:fileencoding=utf8:syntax=make 71 | -------------------------------------------------------------------------------- /share/sake.d/phase3.jq: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # phase3.jq -- Define contents for `$(Meta)/phase3.make`. 3 | # 4 | # jq -r -f phase3.jq 5 | # --arg Meta $(Meta) 6 | # --arg Layouts $(Layouts) 7 | # --arg Root $(Root) 8 | # < $(Meta)/pages-by-id.json 9 | # > $(Meta)/phase3.make 10 | 11 | def basename: 12 | sub("\\.[^/]+$"; "") 13 | ; 14 | 15 | def dependencies: 16 | if .Dependencies 17 | then " " + (.Dependencies | join(" ")) 18 | else "" end 19 | + 20 | if .Datasets 21 | then " " + ([.Datasets[] | basename | "\($Meta)/\(.).json"] | join(" ")) 22 | else "" end 23 | ; 24 | 25 | def dataset: 26 | if .Datasets 27 | then " " + ([.Datasets[] | basename | "-j\(.):\(.).json"] | join(" ")) 28 | else "" end 29 | ; 30 | 31 | def flags: 32 | if .Flags 33 | then " " + (.Flags | join(" ")) 34 | else "" end 35 | ; 36 | 37 | def page: 38 | " -jpage:pages/\(.Id).json" 39 | ; 40 | 41 | # %.html: _site/%.html ; 42 | # blog/%.html: _site/blog/%.html ; 43 | def page_target: 44 | map(.Path) 45 | | unique[] 46 | | "\(.)%.html: \($Root)/\(.)%.html ;" 47 | ; 48 | 49 | def layout: 50 | " $(Layouts)/\(.Layout).html" 51 | ; 52 | 53 | # _site/jqt/index.html: content/index.md layouts/page.html content/macros.m content/LINKS.txt content/EXAMPLE.txt 54 | # $(info ==> $@) 55 | # @$(JQT) -d $< -jpage:pages/index.json layouts/page.html | $(DETAILS) > $@ 56 | # ... 57 | # _site/jqt/blog/2017-04-13-hello.html: content/blog/2017-04-13-hello.md layouts/page.html 58 | # $(info ==> $@) 59 | # @$(JQT) -d $< -jpage:pages/blog/2017-04-13-hello.json layouts/page.html | $(DETAILS) > $@ 60 | def page_rule: 61 | .[] | 62 | "\($Root)/"+.URL+": " + .Source + dependencies, 63 | "\t$(info ==> $@)", 64 | "\t$(JQT) -d $<" + dataset + flags + page + layout + " | $(DETAILS) > $@" 65 | ; 66 | 67 | # 68 | # Output makefile 69 | # 70 | 71 | "__phase_3 := 1\n", 72 | page_target, # for each path 73 | "", 74 | page_rule, # for each page 75 | "", 76 | "# \u0076im:syntax=make" 77 | 78 | # vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=jq 79 | -------------------------------------------------------------------------------- /docs/content/jqt.1.text: -------------------------------------------------------------------------------- 1 | % JQT(1) Version <%include ../VERSION> | jq based web template engine 2 | % 3 | % Aug 2016 4 | 5 | # NAME 6 | 7 | **jqt** – jq based web template engine 8 | 9 | # SYNOPSIS 10 | 11 | | **jqt** [**-h** | **-p** | **-V** ] 12 | | **jqt** [options] < infile > result 13 | | **jqt** [options] infile > result 14 | | **jqt** [options] infile result 15 | 16 | # DESCRIPTION 17 | 18 | **jqt** orchestrates several shell utilities to transform MarkDown text and 19 | YAML or JSON data into a final HTML document. The transformation is driven by a template, 20 | where HTML is mixed with **jq** snippets to implement the transformation logic. 21 | 22 | # OPTIONS 23 | 24 | <%include content/macros.m>& 25 | <%include content/opt/4.txt> 26 | <%include content/opt/C.txt> 27 | <%include content/opt/D.txt> 28 | <%include content/opt/d.txt> 29 | <%include content/opt/e.txt> 30 | <%include content/opt/H.txt> 31 | <%include content/opt/h.txt> 32 | <%include content/opt/I.txt> 33 | <%include content/opt/i.txt> 34 | <%include content/opt/j.txt> 35 | <%include content/opt/L.txt> 36 | <%include content/opt/M.txt> 37 | <%include content/opt/m.txt> 38 | <%include content/opt/P.txt> 39 | <%include content/opt/p.txt> 40 | <%include content/opt/r.txt> 41 | <%include content/opt/S.txt> 42 | <%include content/opt/T.txt> 43 | <%include content/opt/t.txt> 44 | <%include content/opt/V.txt> 45 | <%include content/opt/w.txt> 46 | 47 | # FILES 48 | 49 | /usr/local/share/jqt/libjqt.m 50 | : Initialization file for `gpp`. 51 | 52 | /usr/local/share/jqt/\*.m 53 | : Macro example files for `gpp`. 54 | 55 | # BUGS 56 | 57 | See GitHub issues: 58 | 59 | # AUTHOR 60 | 61 | **jqt** was written by Joan Josep Ordinas Rosa . 62 | 63 | # COPYRIGHT 64 | 65 | Copyright © 2015 Joan Josep Ordinas Rosa. 66 | **jqt** is licensed under the MIT license (code) and the CC-BY-3.0 license (documents). 67 | 68 | # SEE ALSO 69 | 70 | **jq(1)**, **gpp(1)**, **pandoc(1)**, **sake(1)** 71 | 72 | **jqt** home page: 73 | 74 | 77 | -------------------------------------------------------------------------------- /docs/content/sake.1.text: -------------------------------------------------------------------------------- 1 | % SAKE(1) Version 0.1.0 | Build-automation utility for static web sites 2 | % 3 | % November 2018 4 | 5 | # NAME 6 | 7 | **sake** – Build-automation utility for static web sites 8 | 9 | # SYNOPSIS 10 | 11 | | **sake** [command] [[options] [variable=definition] ...] 12 | 13 | # DESCRIPTION 14 | 15 | **sake** is a simple wrapper to _GNU Make_. 16 | 17 | # OPTIONS 18 | 19 | Inherit from _GNU Make_. 20 | 21 | # COMMANDS 22 | 23 | build 24 | : Build the static web site. 25 | 26 | clean 27 | : Remove generated static web site, 28 | 29 | clobber 30 | : Remove all generated files and directories. 31 | 32 | configure 33 | : Configure metadata used in the build process. 34 | 35 | dag 36 | : Show directed acyclic graph of dependencies. 37 | 38 | h5.lint 39 | : Verify generated HTML 5 files. 40 | 41 | h5.valid 42 | : Validate generated HTML 5 files. 43 | 44 | help 45 | : Show a short help message. 46 | 47 | list 48 | : Show the list of commands available. 49 | 50 | new [name=_path_] [skel=(basic|blog)] 51 | : Create a new static web site. 52 | 53 | nuke 54 | : Remove generated metadata. 55 | 56 | touch 57 | : Touch the configuration file and build again the site. 58 | 59 | # FILES 60 | 61 | /usr/local/share/jqt/sake/sake.d 62 | : Library of makefiles used by `sake`. 63 | 64 | /usr/local/share/jqt/milligram 65 | : Minimal CSS framework. 66 | 67 | Sakefile 68 | : Mandatory user makefile. 69 | 70 | # ENVIRONMENT 71 | 72 | JQTLIB (exported) 73 | : Path to files used by `sake`. 74 | 75 | NCORES (imported) 76 | : Number of cores in the build machine. 77 | 78 | # BUGS 79 | 80 | See GitHub issues: 81 | 82 | # AUTHOR 83 | 84 | **sake** was written by Joan Josep Ordinas Rosa . 85 | 86 | # COPYRIGHT 87 | 88 | Copyright © 2015 Joan Josep Ordinas Rosa. 89 | **sake** is licensed under the MIT license (code) and the CC-BY-3.0 license (documents). 90 | 91 | # SEE ALSO 92 | 93 | **make(1)**, **jq(1)**, **jqt(1)** 94 | 95 | **jqt** home page: 96 | 97 | 100 | -------------------------------------------------------------------------------- /docs/Sakefile: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Project: jqt 3 | # Author: jordinas@gmail.com 4 | # Description: Makefile for JQT web site management. 5 | # Published: https://fadado.github.io/jqt/ 6 | # 7 | # Project specific makefile. All the imported modules are expected to be 8 | # independent, valid for any project without any change. This should be 9 | # the only makefile to edit by hand! 10 | # 11 | # Variables modified: 12 | # JQTFLAGS 13 | 14 | ######################################################################## 15 | # Variables to define before include if default values must be changed. 16 | ######################################################################## 17 | 18 | #Meta := .meta 19 | #VERBOSE := 1 20 | #TRACE := 1 21 | 22 | ######################################################################## 23 | # Starting makefile 24 | ######################################################################## 25 | 26 | include $(JQTLIB)/sake.d/main.make 27 | 28 | ifdef __build 29 | 30 | ######################################################################## 31 | # Variables to define after include if default values must be changed. 32 | ######################################################################## 33 | 34 | #JQTFLAGS += 35 | #VNU := java -jar /usr/local/vnu/vnu.jar 36 | #JQTFLAGS += ... 37 | 38 | # Add some Pandoc options 39 | JQTFLAGS += -5 --toc-depth=4 #-S 40 | 41 | ######################################################################## 42 | # experimental 43 | ######################################################################## 44 | 45 | $(PagesHTML): $(Blocks)/filters.jq 46 | 47 | tree: 48 | tree \ 49 | -J \ 50 | $(Root) \ 51 | -P '*.html' \ 52 | --dirsfirst 53 | 54 | # -H $(Root) 55 | # -T "Sitemap" 56 | # -o $@ 57 | 58 | purge: 59 | killall jqt jq pandoc 60 | 61 | depend: $(Meta)/phase3d.make 62 | cat $< | egrep -v '^#|^$$' | cut -c -72 - | sed 's/$$/.../' 63 | 64 | # TODO: new, new-templates, man page, SITE section on web, taxonomies (flags, series...) 65 | # TODO: enhance `dag` command 66 | # TODO: -t -W -B ??? 67 | 68 | # TODO: show content pending to render? 69 | #newer: $(Meta)/lastbuild 70 | 71 | endif # __build 72 | 73 | # vim:ai:sw=8:ts=8:noet:fileencoding=utf8:syntax=make 74 | -------------------------------------------------------------------------------- /share/milligram/form.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 | // Form 11 | // –––––––––––––––––––––––––––––––––––––––––––––––––– 12 | 13 | &define{_input}{ 14 | input[type='email']$1, 15 | input[type='number']$1, 16 | input[type='password']$1, 17 | input[type='search']$1, 18 | input[type='tel']$1, 19 | input[type='text']$1, 20 | input[type='url']$1, 21 | input[type='color']$1, 22 | input[type='date']$1, 23 | input[type='month']$1, 24 | input[type='week']$1, 25 | input[type='datetime']$1, 26 | input[type='datetime-local']$1, 27 | input:not([type])$1, 28 | textarea, 29 | select 30 | } 31 | 32 | &_input{} { 33 | appearance: none // Removes awkward default styles on some inputs for iOS 34 | background-color: transparent; 35 | border: 0.1rem solid &ColorQuaternary; 36 | border-radius: .4rem; 37 | box-shadow: none; 38 | box-sizing: inherit // Forced to replace inherit values of the normalize.css 39 | height: 3.8rem; 40 | padding: .6rem 1.0rem; // The .6rem vertically centers text on FF, ignored by Webkit 41 | width: 100%; 42 | } 43 | 44 | &_input{:focus} { 45 | border: 0.1rem solid &ColorPrimary; 46 | outline: 0; 47 | } 48 | 49 | select { 50 | background: url('data:image/svg+xml;utf8,') center right no-repeat; 51 | padding-right: 3rem; 52 | } 53 | 54 | select:focus { 55 | background-image: url('data:image/svg+xml;utf8,') 56 | } 57 | 58 | textarea { 59 | min-height: 6.5rem; 60 | } 61 | 62 | label, 63 | legend { 64 | display: block; 65 | font-size: 1.6rem; 66 | font-weight: 700; 67 | margin-bottom: .5rem; 68 | } 69 | 70 | fieldset { 71 | border-width: 0; 72 | padding: 0; 73 | } 74 | 75 | input[type='checkbox'], 76 | input[type='radio'] { 77 | display: inline; 78 | } 79 | 80 | &BEM{label}{}{inline} { 81 | display: inline-block; 82 | font-weight: normal; 83 | margin-left: .5rem; 84 | } 85 | 86 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss 87 | -------------------------------------------------------------------------------- /bump-version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # works with a file called VERSION in the current directory, 4 | # the contents of which should be a semantic version number 5 | # such as "1.2.3" 6 | 7 | # this script will display the current version, automatically 8 | # suggest a "minor" version update, and ask for input to use 9 | # the suggestion, or a newly entered value. 10 | 11 | # once the new version number is determined, the script will 12 | # pull a list of changes from git history, prepend this to 13 | # a file called CHANGES (under the title of the new version 14 | # number) and create a GIT tag. 15 | 16 | PUSH=${1:-No} 17 | 18 | if [[ -f VERSION ]]; then 19 | declare -r CURRENT_VERSION=$(&2 "Current version : ${CURRENT_VERSION}" 21 | set -- ${CURRENT_VERSION//./ } 22 | declare -i V_MAJOR=$1 V_MINOR=$2 V_PATCH=$3 23 | V_MINOR+=1 24 | V_PATCH=0 25 | declare -r SUGGESTED_VERSION="${V_MAJOR}.${V_MINOR}.${V_PATCH}" 26 | read 1>&2 -p "Enter a version number [${SUGGESTED_VERSION}]: " 27 | if [[ -z $REPLY ]]; then 28 | NEXT_VERSION=${SUGGESTED_VERSION} 29 | else 30 | NEXT_VERSION=${REPLY} 31 | fi 32 | echo 1>&2 "Will set new version to be ${NEXT_VERSION}" 33 | echo -n ${NEXT_VERSION} > VERSION 34 | { echo "Version ${NEXT_VERSION}:" 35 | git log --pretty=format:" - %s" "v${CURRENT_VERSION}"...HEAD 36 | echo -e '\n' 37 | cat CHANGES 38 | } > /tmp/$$-changes 39 | cp /tmp/$$-changes CHANGES 40 | rm /tmp/$$-changes 41 | git add CHANGES VERSION 42 | sed -i "s/^declare -r VERSION=.*$/declare -r VERSION='${NEXT_VERSION}'/" bin/jqt 43 | sed -i "s/^version: *.*/version: ${NEXT_VERSION}/" docs/config.yaml 44 | git commit -am "Version bump to ${NEXT_VERSION}" 45 | git tag -a -m "Tagging version ${NEXT_VERSION}" "v${NEXT_VERSION}" 46 | [[ $PUSH == yes ]] && git push origin --tags 47 | else 48 | echo 1>&2 'Could not find a VERSION file' 49 | read 1>&2 -p 'Create a new VERSION file [y/yes]? ' 50 | case ${REPLY} in 51 | ''|[Yy]|[Yy][Ee][Ss]) 52 | echo -n '0.1.0' > VERSION 53 | { echo 'Version 0.1.0' 54 | git log --pretty=format:' - %s' 55 | echo -e '\n' 56 | } >> CHANGES 57 | git add VERSION CHANGES 58 | git commit -m 'Added VERSION and CHANGES files, version bump to v0.1.0' 59 | git tag -a -m 'Tagging version 0.1.0' 'v0.1.0' 60 | [[ ${PUSH} == yes ]] && git push origin --tags 61 | ;; 62 | *) echo 1>&2 'Ok' 63 | ;; 64 | esac 65 | fi 66 | 67 | exit 68 | 69 | # vim:ai:sw=4:ts=4:et:syntax=sh 70 | -------------------------------------------------------------------------------- /share/milligram/button.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 | // Button 11 | // –––––––––––––––––––––––––––––––––––––––––––––––––– 12 | 13 | // Macros 14 | 15 | &define{_buttons}{ 16 | .button$1, 17 | button$1, 18 | input[type='button']$1, 19 | input[type='reset']$1, 20 | input[type='submit']$1 21 | } 22 | 23 | &define{_buttons_active}{ 24 | &_buttons{$1:hover}, 25 | &_buttons{$1:focus} 26 | } 27 | 28 | // Rules 29 | 30 | &_buttons{} { 31 | background-color: &ColorPrimary; 32 | border: 0.1rem solid &ColorPrimary; 33 | border-radius: .4rem; 34 | color: &ColorInitial; 35 | cursor: pointer; 36 | display: inline-block; 37 | font-size: 1.1rem; 38 | font-weight: 700; 39 | height: 3.8rem; 40 | letter-spacing: .1rem; 41 | line-height: 3.8rem; 42 | padding: 0 3.0rem; 43 | text-align: center; 44 | text-decoration: none; 45 | text-transform: uppercase; 46 | white-space: nowrap; 47 | } 48 | 49 | &_buttons_active { 50 | background-color: &ColorSecondary; 51 | border-color: &ColorSecondary; 52 | color: &ColorInitial; 53 | outline: 0; 54 | } 55 | 56 | &_buttons{&BEM{button}{}{disabled}}, 57 | &_buttons{[disabled]} { 58 | cursor: default; 59 | opacity: .5; 60 | } 61 | 62 | &_buttons_active{&BEM{button}{}{disabled}}, 63 | &_buttons_active{[disabled]} { 64 | background-color: &ColorPrimary; 65 | border-color: &ColorPrimary; 66 | } 67 | 68 | &_buttons{&BEM{button}{}{outline}} { 69 | background-color: transparent; 70 | color: &ColorPrimary; 71 | } 72 | 73 | &_buttons_active{&BEM{button}{}{outline}} { 74 | background-color: transparent; 75 | border-color: &ColorSecondary; 76 | color: &ColorSecondary; 77 | } 78 | 79 | &_buttons_active{&BEM{button}{}{outline}&BEM{button}{}{disabled}}, 80 | &_buttons_active{&BEM{button}{}{outline}[disabled]} { 81 | border-color: inherit; 82 | color: &ColorPrimary; 83 | } 84 | 85 | &_buttons{&BEM{button}{}{clear}} { 86 | background-color: transparent; 87 | border-color: transparent; 88 | color: &ColorPrimary; 89 | } 90 | 91 | &_buttons_active{&BEM{button}{}{clear}} { 92 | background-color: transparent; 93 | border-color: transparent; 94 | color: &ColorSecondary; 95 | } 96 | 97 | &_buttons_active{&BEM{button}{}{clear}&BEM{button}{}{disabled}}, 98 | &_buttons_active{&BEM{button}{}{clear}[disabled]} { 99 | color: &ColorPrimary; 100 | } 101 | 102 | // vim:ts=2:sw=2:ai:et:fileencoding=utf-8:syntax=scss 103 | -------------------------------------------------------------------------------- /tests/jqt/expected/expr-00.txt: -------------------------------------------------------------------------------- 1 | ======================= 2 | Tests about expressions 3 | ======================= 4 | 5 | Escape: \\ TB (\t) LF(\n) CR(\r) 6 | 7 | Interpolated string: true 8 | Interpolated string: false 9 | Interpolated string: null 10 | Interpolated string: Neque porro quisquam 11 | Interpolated string: 3.141592653589793 12 | 13 | _______________________ 14 | _______________________ 15 | 16 | Not vanished line: true 17 | Not vanished line: Neque porro quisquam 18 | Not vanished line: 3.141592653589793 19 | Not vanished line: [7,6,5,4,3,2,1] 20 | Not vanished line: {"b":true,"s":"Neque","n":3.14} 21 | 22 | Nested expression: ===3.141592653589793=== 23 | Nested expression: ===Neque porro quisquam=== 24 | Nested expression: =-*-= 25 | 26 | Nested expression: ===3.141592653589793=== 27 | Nested expression: ===Neque porro quisquam=== 28 | Nested expression: =-*-= 29 | 30 | Local name: 3.141592653589793 31 | Local name: ["2","4","6","8","10","12","14"] 32 | Local name: ["10","12","14","2","4","6","8"] 33 | 34 | Repeated line: 0 35 | Repeated line: 1 36 | Repeated line: 2 37 | Repeated line: 3 38 | Repeated line: 4 39 | Repeated line: 5 40 | Repeated line: 6 41 | Repeated line: b 42 | Repeated line: n 43 | Repeated line: s 44 | Repeated line: 7 45 | Repeated line: 6 46 | Repeated line: 5 47 | Repeated line: 4 48 | Repeated line: 3 49 | Repeated line: 2 50 | Repeated line: 1 51 | 52 | Repeated line: 3.141592653589793 53 | Repeated line: 6.283185307179586 54 | Repeated line: 9.42477796076938 55 | Repeated line: 12.566370614359172 56 | 57 | Repeated line: 1 58 | Repeated line: 2 59 | Repeated line: 3 60 | Repeated line: 4 61 | Repeated line: 5 62 | Repeated line: 6 63 | Repeated line: 7 64 | 65 | Repeated line: 1 66 | Repeated line: 2 67 | Repeated line: 3 68 | Repeated line: 4 69 | Repeated line: 5 70 | Repeated line: 6 71 | Repeated line: 7 72 | 73 | The value of pi is 3.141592653589793. 74 | Pi squared: 6.283185307179586 75 | Pi squared: 6.283185307179586 76 | Array [7,6,5,4,3,2,1] has length 7 77 | Array [7,6,5,4,3,2,1] has length 7 78 | 79 | Array $a has value 7 at position 0 80 | Array .array and array $a are equal? (true) 81 | Values sorted as strings: ["10","12","14","2","4","6","8"] 82 | 83 |
  • 1
  • 84 |
  • 2
  • 85 |
  • 3
  • 86 |
  • 4
  • 87 |
  • 5
  • 88 |
  • 6
  • 89 |
  • 7
  • 90 | 91 | Slice: [7,6,5,4] 92 | Limit: [7,6,5,4] 93 | 94 | Modulo: 2 95 | Modulo: 2 96 | 97 | Object: {"a":1,"b":2} 98 | 99 | Fibonacci(10): [0,1,1,2,3,5,8,13,21,34] 100 | Fibonacci(10): 34 101 | Fibonacci(10): 34 102 | 103 | ======================= 104 | 105 | -------------------------------------------------------------------------------- /share/sake.d/configuration.make: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # configuration.make -- Global GMake configuration. 3 | # 4 | # Debugging variables: 5 | # VERBOSE 6 | # TRACE 7 | 8 | export TRACE ?= 9 | export VERBOSE ?= 10 | 11 | ######################################################################## 12 | # Prerequisites. 13 | ######################################################################## 14 | 15 | # We are using some of the newest GNU Make features... so require GNU 16 | # Make version >= 3.82. 17 | version_test := $(filter 3.82,$(firstword $(sort $(MAKE_VERSION) 3.82))) 18 | ifndef version_test 19 | $(error GNU Make version $(MAKE_VERSION); version >= 3.82 is needed) 20 | endif 21 | 22 | # Only one target at the same time. 23 | MAKECMDGOALS ?= build 24 | 25 | ######################################################################## 26 | # Make configuration. 27 | ######################################################################## 28 | 29 | #!# Use renamed makefile 30 | #!MAKE += --makefile=Sakefile 31 | 32 | # Disable builtins. 33 | MAKEFLAGS += --no-builtin-rules 34 | MAKEFLAGS += --no-builtin-variables 35 | 36 | # Warn when an undefined variable is referenced. 37 | MAKEFLAGS += --warn-undefined-variables 38 | 39 | # Make will not print the recipe used to remake files. 40 | $(VERBOSE).SILENT: 41 | 42 | # Eliminate use of the built-in implicit rules. Also clear out the 43 | # default list of suffixes for suffix rules. 44 | .SUFFIXES: 45 | 46 | # Sets the default goal to be used if no targets were specified on the 47 | # command line. 48 | .PHONY: build 49 | .DEFAULT_GOAL := build 50 | 51 | # Default shell: if we require GNU Make, why not require Bash? 52 | SHELL := /bin/bash 53 | 54 | # The argument(s) passed to the shell are taken from the variable 55 | # .SHELLFLAGS. 56 | .SHELLFLAGS := -o errexit -o pipefail -o nounset -c 57 | 58 | # Make will delete the target of a rule if it has changed and its recipe 59 | # exits with a nonzero exit status. 60 | .DELETE_ON_ERROR: 61 | 62 | # Enable a second expansion of the prerequisites. 63 | .SECONDEXPANSION: 64 | 65 | ######################################################################## 66 | # Common macros 67 | ######################################################################## 68 | 69 | # Hacks for string manipulation. 70 | #!comma := , 71 | #!empty := 72 | #!space := $(empty) $(empty) 73 | #!tab := $(empty) $(empty) 74 | 75 | # Hack for list manipulation. 76 | #!define rest = 77 | #!$(wordlist 2,2147483648,$1) 78 | #!endef 79 | 80 | # File name without extension nor directory. 81 | #!define filename 82 | #!$(basename $(notdir $1)) 83 | #!endef 84 | 85 | # vim:ai:sw=8:ts=8:noet:fileencoding=utf8:syntax=make 86 | -------------------------------------------------------------------------------- /tests/jqt/expr-00.jqt: -------------------------------------------------------------------------------- 1 | ======================= 2 | Tests about expressions 3 | ======================= 4 | 5 | Escape: \\ TB (\t) LF(\n) CR(\r) 6 | 7 | Interpolated string: {{.yes}} 8 | Interpolated string: {{.not}} 9 | Interpolated string: {{.nil}} 10 | Interpolated string: {{.string}} 11 | Interpolated string: {{.number}} 12 | 13 | _______________________ 14 | Vanished line: {{empty}} 15 | Vanished line: {{.not//empty}} 16 | Vanished line: {{.nil//empty}} 17 | _______________________ 18 | 19 | Not vanished line: {{.yes//empty}} 20 | Not vanished line: {{.string//empty}} 21 | Not vanished line: {{.number//empty}} 22 | Not vanished line: {{.array//empty}} 23 | Not vanished line: {{.object//empty}} 24 | 25 | Nested expression: {{if .yes then "==={{.number}}===" else "==={{.string}}===" end}} 26 | Nested expression: {{if .not then "==={{.number}}===" else "==={{.string}}===" end}} 27 | Nested expression: {{"={{"-{{"*"}}-"}}="}} 28 | 29 | Nested expression: {{ 30 | if .yes 31 | then "===\(.number)===" 32 | else "===\(.string)===" 33 | end 34 | }} 35 | Nested expression: {{ 36 | if .not 37 | then "===\(.number)===" 38 | else "===\(.string)===" 39 | end 40 | }} 41 | Nested expression: {{ 42 | "=\( 43 | "-\( 44 | "*" 45 | )-" 46 | )=" 47 | }} 48 | 49 | Local name: {{. as $jqt | $jqt.number}} 50 | Local name: {{. as $jqt | $jqt.array | map(.*2) | sort | map(tostring)}} 51 | Local name: {{. as $jqt | $jqt.array | map(.*2) | map(tostring) | sort}} 52 | 53 | Repeated line: {{.array | keys[]}} 54 | Repeated line: {{.object | keys[]}} 55 | Repeated line: {{.array[]}} 56 | 57 | Repeated line: {{. as $jqt | range(1;5) | .*$jqt.number}} 58 | 59 | Repeated line: {{.array | sort[]}} 60 | 61 | Repeated line: {{ 62 | if .nil == null 63 | then .array | sort[] 64 | else empty end 65 | }} 66 | 67 | {% .number %}The value of pi is {{.}}. 68 | {% .number %}Pi squared: {{.*2}} 69 | {% .number*2 %}Pi squared: {{.}} 70 | {% .array %}Array {{.}} has length {{.|length}} 71 | {% .array %}Array {{.}} has length {{length}} 72 | 73 | {% .array as $a %}Array $a has value {{$a[0]}} at position 0 74 | {% .array as $a | $jqt %}Array .array and array $a are equal? ({{$a == $jqt.array)}} 75 | {% .array | map(.*2 | tostring) | sort %}Values sorted as strings: {{.}} 76 | 77 | {% .array | sort[] | tostring | "{{.}}" | "
  • {{.}}
  • " %}{{.}} 78 | 79 | Slice: {{ (.array | sort | reverse)[:4]}} 80 | Limit: {{[limit(4; .array | sort | reverse[])]}} 81 | 82 | Modulo: {{ 2 % 7 }} 83 | {% 2 % 7 %}Modulo: {{.}} 84 | 85 | Object: {{ {a:1}+{b:2} }} 86 | 87 | Fibonacci(10): {{ [limit(10; fibonacci)] }} 88 | Fibonacci(10): {{ [limit(10; fibonacci)][-1] }} 89 | Fibonacci(10): {{ [limit(10; fibonacci)] | reverse[0] }} 90 | 91 | ======================= 92 | -------------------------------------------------------------------------------- /docs/content/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Home 3 | title: Welcome to jqt 4 | description: Could be jq the basis for a web template engine? 5 | keywords: jqt, jq, template engine 6 | updated: "2016-08-28T10:27:09Z" 7 | Layout: page 8 | Dependencies: [content/EXAMPLE.txt] 9 | --- 10 | <%include content/macros.m>& 11 | <%include content/LINKS.txt>& 12 | 13 | # Welcome to <%cite jqt> 14 | 15 | 19 |

    Editing is a rewording activity.
    Alan J. Perlis

    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 | ..., "\(.title)", ... 35 | ``` 36 | 37 | ### Conditional expansion 38 | 39 | ```html 40 | ..., "", ... 41 | ``` 42 | 43 | ### Repeated expansion 44 | 45 | ```html 46 | ..., "", ... 47 | ``` 48 | 49 | In these examples the strings expand, vanish, or multiply without any 50 | explicit `if` or `for`! 51 | 52 | ## <%cite jqt> 53 | 54 | To write [_jq_][JQ] scripts using strings with interpolations is not the idea we have 55 | for a template language. We need some syntactic sugar, and this is provided by 56 | <%cite jqt>: you write templates in a very fashionable style, the templates 57 | are translated into a [_jq_][JQ] script and then `jq` is feed with the created 58 | script and some content and data in [JSON][JSON] format… and the magic is done! 59 | 60 | ### Syntactic sugar 61 | 62 | And, how do the _syntactic sugar_ looks like? Do you think the following 63 | example seems to be a template? 64 | 65 | <%include content/EXAMPLE.txt>& 66 | 67 | ### Status 68 | 69 | This site is built using <%cite jqt>, and is itself in his implementation a kind of 70 | tutorial about <%cite jqt>. 71 | If you want to learn how to use <%cite jqt> see all the different sections of this site: 72 | 73 | * [Template engine](./engine.html) 74 | * [Page structure](./structure.html) 75 | * [Authoring content](./content.html) 76 | * [Data model](./data.html) 77 | 78 | And don’t forget to study this documentation source code in the repository 79 | [`docs`](https://github.com/fadado/jqt/tree/master/docs) directory! 80 | 81 | <%cite jqt> is developed under the _Fedora_ Linux 82 | distribution, and a lot of portability issues are expected at this stage of 83 | development. Please, use the project [GitHub repository][REPO] features if you 84 | want to collaborate or send any kind of questions. 85 | 86 | <# 87 | vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=markdown 88 | #> 89 | -------------------------------------------------------------------------------- /CHANGES: -------------------------------------------------------------------------------- 1 | Version 0.5.1: 2 | - Created jqt.make 3 | - Started blog 4 | - Segregated layouts 5 | - Changed top level object name 6 | - Introspected menu 7 | - Generated sitemap 8 | - Completed makefile modules 9 | - Rules generated introspecting 10 | - Generated makefile for extra dependencies 11 | - Generated JSON for pages 12 | - use addsuffix function 13 | - Enabled second expansion 14 | - Generate site.json 15 | - New target "metadata" 16 | - Protected target clobber 17 | - Implemented default globals 18 | - Added favicon 19 | - General solution for assets 20 | - New styles organization 21 | - Restructuring docs 22 | - New tests 23 | - Created directory for macros 24 | - Enhanced README 25 | 26 | Version 0.5.0: 27 | - Version bump to 0.5.0 28 | - Segregated common macros library 29 | - General edition 30 | - Fixed EOL on comments 31 | - Segregated BEM macros 32 | - Added syntax tables 33 | - Unified documentation for JSON and CSS macros 34 | - Migrated JSON macro syntax 35 | - CSS macros sigil changed to $ 36 | - Reorganized .jq filters 37 | - Minor editions 38 | - Joined arg and value lines 39 | - New normalize.css 40 | - Implemented -w 41 | - Added paragraph after main heading 42 | - Print styles 43 | - Better metadata 44 | - small footer 45 | - details 46 | - main element 47 | 48 | Version 0.4.0: 49 | - XHTMl5 50 | - New CSS module 51 | - More border-radius 52 | - Polished names 53 | - More modular CSS 54 | - Better macro BEM, with escape 55 | - Macro BEM 56 | - Renamed some classes 57 | - Added scaling parameters 58 | - Better CSS minify 59 | - Referencing pandoc 60 | - Going to BEM 61 | - Floating TOC 62 | - Migrating to a new sheet style system 63 | - New CSS preprocessor 64 | - Fix: chicken egg problem #2 65 | - Revised english 66 | 67 | Version 0.3.0: 68 | - New content model 69 | - Managed YAML with MarkDown snippets 70 | - New top level menu 71 | - Generate man pages when install 72 | - Added all MP modes 73 | - Macros for CSS colors 74 | - Refactoring makefiles 75 | 76 | Version 0.2.0: 77 | - Finished site structure and minimal documentation 78 | - Better content sections 79 | - Better skip tables 80 | - Man page ok 81 | - Modularized options 82 | - Completed document.md first version 83 | - Fusion of sub-makefiles 84 | - Added analytics 85 | - Integrated yq 86 | - Completed hello.md and engine.md first versions. 87 | - Refactorized macros 88 | - Started documentation blueprint 89 | - Created auxiliar MD files 90 | - Revised help information 91 | - Do not minify HTML 92 | - Implement the block concept 93 | - Trailing line in snippets removed 94 | - Only two global objects: .front and .body 95 | - Classify files in directories 96 | - Refactoring several files, added local macros, etc. 97 | - Refactoring global pipes 98 | - Link to releases 99 | - Macro process CSS 100 | 101 | Version 0.1.0 102 | - In principio 103 | 104 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Conventions 2 | 3 | ## Extension conventions for content files 4 | 5 | The files in the `content` directory must follow some conventions in the file 6 | extensions: 7 | 8 | * `*.md`: Web site pages. 9 | * `*.text`: Partial MarkDown to be included and other unrelated MarkDown files. 10 | 11 | The files in the `data` directory must follow some conventions in the file 12 | extensions: 13 | 14 | * `*.md`: MarkDown snippets in front-matter. 15 | * `*.csv`: CSV data files. 16 | * `*.json`: JSON documents. 17 | * `*.yaml`: YAML documents. 18 | 19 | # Variables 20 | 21 | Capitalized names are for global predefined variables. 22 | 23 | ## Site variables 24 | 25 | All members defined in the configuration file, except `defaults`, and the 26 | predefined variables: 27 | 28 | * `.site.Assets` 29 | * `.site.Blocks` 30 | * `.site.Content` 31 | * `.site.Data` 32 | * `.site.Root` 33 | * `.site.Layouts` 34 | * `.site.Meta` 35 | * `.site.Styles` 36 | 37 | In the configuration file you can assign new values to all predefined variables 38 | except `Meta`, with default value defined in the file `make.d/Makefile.make`. 39 | You can modify this variable at the very beggining of your `Sakefile`. 40 | 41 | ## Page variables 42 | 43 | Front-matter members and the predefined variables. 44 | 45 | ### Read only variables 46 | 47 | * `.page.Base` 48 | * `.page.Date` 49 | * `.page.Filename` 50 | * `.page.Id` 51 | * `.page.Layout` 52 | * `.page.Path` 53 | * `.page.Section` 54 | * `.page.Slug` 55 | * `.page.Source` 56 | * `.page.URL` 57 | 58 | ### Variables merged with defaults 59 | 60 | * `.page.Datasets` 61 | * `.page.Dependencies` 62 | * `.page.Flags` 63 | 64 | ### Source for pathname related variables 65 | 66 | ``` 67 | Slug 68 | |---^---| 69 | content/name.html 70 | |-^| 71 | Id 72 | 73 | Section Slug 74 | |--^-| |--^----| 75 | content/extras/name.html 76 | |-------v-| 77 | |--v--| Id 78 | Path 79 | 80 | Section Slug 81 | |------^-----| |---^---| 82 | content/extras/indexes/name.html 83 | |---------------v-| 84 | |-----v-------| Id 85 | Path 86 | ``` 87 | 88 | # _Sake_: static site build automation system 89 | 90 | ## Sakefile 91 | 92 | _Sake_ managed projects must have a makefile named `Sakefile`, and this 93 | makefile must contain the following include: 94 | 95 | include $(SAKE)/make.d/main.make 96 | 97 | ## Current _Sake_ commands 98 | 99 | ``` 100 | Usage: sake [command] [[options] [variable=definition] ...] 101 | Commands: 102 | build clobber dag h5.lint help new 103 | clean configure depend h5.valid list nuke 104 | ``` 105 | 106 | ## Autocompletion 107 | 108 | Hint (on _Fedora_): to enable autocompletion for `sake` do this: 109 | 110 | ``` 111 | $ cd /usr/share/bash-completion/completions 112 | $ sudo sed -i make -e '/^complete -F/s/$/ sake/' 113 | $ sudo ln -s make sake 114 | ``` 115 | 116 | 119 | -------------------------------------------------------------------------------- /bin/cq: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Wraps jq to be able to process CSV 5 | # 6 | 7 | # Options 8 | set -o errexit -o noglob -o nounset -o pipefail 9 | shopt -s expand_aliases 10 | 11 | # Script name 12 | declare -r SELF=${0##*/} 13 | 14 | # Show help 15 | function help { 16 | cat < [file] 19 | 20 | ${SELF} is a wrapper to jq for processing CSV input, applying the given 21 | filter to it CSV text input and producing the filter's results as 22 | CSV or JSON on standard output. 23 | 24 | The options available are ${SELF} specific and also from jq. The ${SELF} 25 | options are: 26 | -h Show this help 27 | -C Output using CSV format (default) 28 | -J Output using JSON format 29 | -Y Output using YAML format 30 | -V Output the jq version 31 | 32 | Some of the jq options include: 33 | -e set the exit status code based on the output 34 | -f Read filter from the file f 35 | -s read (slurp) all inputs into an array; apply filter to it 36 | -S sort keys of objects on output 37 | --arg a v set variable \$a to value v 38 | --argjson a v set variable \$a to JSON value v 39 | --slurpfile a f set variable \$a to an array of values read from f 40 | Not all jq options have sense using ${SELF}. 41 | 42 | For more advanced filters see the jq(1) manpage and 43 | https://stedolan.github.io/jq 44 | EOF 45 | exit $(( $# == 0 )) 46 | } 47 | 48 | # Entry point 49 | function main { 50 | local -i json=0 yaml=0 51 | 52 | local opt 53 | while getopts :hJKVY-: opt; do 54 | case $opt in 55 | h) help ;; 56 | C) ;; 57 | J) json=1 ;; 58 | Y) yaml=1 ;; 59 | V) exec jq --version ;; 60 | -) case $OPTARG in 61 | help) help ;; 62 | CSV|csv) ;; 63 | JSON|json) json=1 ;; 64 | YAML|yaml) yaml=1 ;; 65 | *) OPTIND=$((OPTIND-1)) 66 | break ;; # assume jq option 67 | esac 68 | ;; 69 | ?) OPTIND=$((OPTIND-1)) 70 | break ;; # assume jq option 71 | esac 72 | done 73 | 74 | shift $((OPTIND-1)) 75 | (( $# > 0 )) || help 76 | [[ $1 == '--version' ]] && exec jq --version 77 | 78 | # Is stdin a TTY? 79 | if [[ -t 0 ]]; then 80 | if (( $# >= 2 )); then 81 | # Is the last parameter a regular file? 82 | local last=${!#} 83 | if [[ -f $last ]]; then 84 | # reopen stdin 85 | exec 0< "$last" 86 | # remove last parameter 87 | set -- "${@:1:$(($#-1))}" 88 | fi 89 | fi 90 | fi 91 | 92 | # Wrap jq 93 | if (( json )); then 94 | # Preserve JSON output 95 | csv2json | jq "$@" 96 | elif (( yaml )); then 97 | csv2json | jq "$@" | json2yaml 98 | else 99 | csv2json | jq "$@" | json2csv 100 | fi 101 | 102 | # Exit status is that of the last command executed. 103 | exit 104 | } 105 | 106 | # Call main 107 | main "$@" 108 | 109 | # vim:ai:sw=4:ts=4:et:syntax=sh 110 | -------------------------------------------------------------------------------- /bin/yq: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Wraps jq to be able to process YAML 5 | # 6 | 7 | # Options 8 | set -o errexit -o noglob -o nounset -o pipefail 9 | shopt -s expand_aliases 10 | 11 | # Script name 12 | declare -r SELF=${0##*/} 13 | 14 | # Show help 15 | function help { 16 | cat < [file] 19 | 20 | ${SELF} is a wrapper to jq for processing YAML input, applying the given 21 | filter to it YAML text input and producing the filter's results as 22 | YAML or JSON on standard output. 23 | 24 | The options available are ${SELF} specific and also from jq. The ${SELF} 25 | options are: 26 | -h Show this help 27 | -J Output using JSON format 28 | -C Output using CSV format 29 | -Y Output using YAML format (default) 30 | -V Output the jq version 31 | 32 | Some of the jq options include: 33 | -e set the exit status code based on the output 34 | -f Read filter from the file f 35 | -s read (slurp) all inputs into an array; apply filter to it 36 | -S sort keys of objects on output 37 | --arg a v set variable \$a to value v 38 | --argjson a v set variable \$a to JSON value v 39 | --slurpfile a f set variable \$a to an array of values read from f 40 | Not all jq options have sense using ${SELF}. 41 | 42 | For more advanced filters see the jq(1) manpage and 43 | https://stedolan.github.io/jq 44 | EOF 45 | exit $(( $# == 0 )) 46 | } 47 | 48 | # Entry point 49 | function main { 50 | local -i json=0 csv=0 51 | 52 | local opt 53 | while getopts :hCJKVY-: opt; do 54 | case $opt in 55 | h) help ;; 56 | C) csv=1 ;; 57 | J) json=1 ;; 58 | Y) ;; 59 | V) exec jq --version ;; 60 | -) case $OPTARG in 61 | help) help ;; 62 | CSV|csv) csv=1 ;; 63 | JSON|json) json=1 ;; 64 | YAML|yaml) ;; 65 | *) OPTIND=$((OPTIND-1)) 66 | break ;; # assume jq option 67 | esac 68 | ;; 69 | ?) OPTIND=$((OPTIND-1)) 70 | break ;; # assume jq option 71 | esac 72 | done 73 | 74 | shift $((OPTIND-1)) 75 | (( $# > 0 )) || help 76 | [[ $1 == '--version' ]] && exec jq --version 77 | 78 | # Is stdin a TTY? 79 | if [[ -t 0 ]]; then 80 | if (( $# >= 2 )); then 81 | # Is the last parameter a regular file? 82 | local last=${!#} 83 | if [[ -f $last ]]; then 84 | # reopen stdin 85 | exec 0< "$last" 86 | # remove last parameter 87 | set -- "${@:1:$(($#-1))}" 88 | fi 89 | fi 90 | fi 91 | 92 | # Wrap jq 93 | if (( json )); then 94 | # Preserve JSON output 95 | yaml2json | jq "$@" 96 | elif (( csv )); then 97 | yaml2json | jq "$@" | json2csv 98 | else 99 | yaml2json | jq "$@" | json2yaml 100 | fi 101 | 102 | # Exit status is that of the last command executed. 103 | exit 104 | } 105 | 106 | # Call main 107 | main "$@" 108 | 109 | # vim:ai:sw=4:ts=4:et:syntax=sh 110 | -------------------------------------------------------------------------------- /share/sake.d/phase2_page.jq: -------------------------------------------------------------------------------- 1 | # Called for each source document, from macro BUILD_PAGE_JSON in created 2 | # phase2.make, to build the JSON file for each page. 3 | # 4 | # input is page front-matter converted to JSON | 5 | # jq -S -f phase2_page.jq 6 | # --arg Source $(Content)/.../PAGE.md 7 | # --arg Target $(Meta)/pages/.../PAGE.json 8 | # --arg Meta $(Meta) 9 | # --slurpfile config $(Meta)/config.json 10 | # > $(Meta)/pages/.../PAGE.json 11 | 12 | # Pathname functions 13 | def basename: 14 | sub("\\.[^/]+$"; "") 15 | ; 16 | 17 | def dir: 18 | if test("/") 19 | then sub("/[^/]+$"; "/") 20 | else "" end 21 | ; 22 | 23 | def notdir: 24 | sub("^.*/"; "") 25 | ; 26 | 27 | # `$(Content)/path/to/page.md` => `(../)+` 28 | def page_base: 29 | $Source 30 | | ("../" * (((. / "/") | length) - 2)) // "" 31 | ; 32 | 33 | # `$(Meta)/pages/path/to/page.json` => `path/to/page` 34 | def page_id: 35 | # . as $target 36 | basename | sub($Meta+"/pages/"; "") 37 | ; 38 | 39 | # `$(Meta)/pages/path/to/page.json` => `page` 40 | def page_filename: 41 | # . as $target 42 | notdir | basename 43 | ; 44 | 45 | # `$(Meta)/pages/path/to/page.json` => `path/to/` 46 | def page_path: 47 | # . as $obj 48 | .Id | dir 49 | ; 50 | 51 | # `$(Meta)/pages/path/to/page.json` => `path/to` 52 | def page_section: 53 | #. as $obj 54 | if $Target | test("(? `page.html` 60 | def page_slug: 61 | # . as $obj 62 | .Filename + ".html" 63 | ; 64 | 65 | # `$(Meta)/pages/path/to/page.json` => `path/to/page.html` 66 | def page_url: 67 | # . as $obj 68 | .Path + .Slug 69 | ; 70 | 71 | # Extract date if present. 72 | def page_date: 73 | # . as $obj 74 | .Filename | 75 | (capture("^(?\\d{4}-\\d{2}-\\d{2})-") | .YMD) 76 | // "" 77 | ; 78 | 79 | ######################################################################## 80 | # Output object for each page 81 | ######################################################################## 82 | 83 | def defaults: 84 | $Target 85 | | page_id as $id 86 | | reduce $config[0].defaults[] as $d 87 | ({}; if $id | test("^" + $d.idprefix) 88 | then . + $d.properties 89 | else . end) 90 | ; 91 | 92 | def properties: 93 | $Target 94 | | { 95 | Base: page_base, 96 | Filename: page_filename, 97 | Source: $Source, 98 | Id: page_id 99 | } 100 | # in the following order! 101 | | .Path = page_path 102 | | .Section = page_section 103 | | .Slug = page_slug 104 | | .URL = page_url 105 | | .Date = page_date 106 | ; 107 | 108 | ######################################################################## 109 | # Generate object to be found in `.page`. 110 | ######################################################################## 111 | 112 | def merge($k; $d; $f): 113 | if ($k|in($d)) and ($k|in($f)) 114 | then .[$k] = $d[$k] + $f[$k] # merge list 115 | else . end 116 | ; 117 | 118 | . as $f # front_matter 119 | | defaults as $d 120 | | properties as $p 121 | | $d * $f + $p 122 | | merge("Datasets"; $d; $f) 123 | | merge("Dependencies"; $d; $f) 124 | | merge("Flags"; $d; $f) 125 | 126 | # vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=jq 127 | -------------------------------------------------------------------------------- /share/sake.d/phase2.jq: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # phase2.jq -- Define contents for `$(Meta)/phase2.make`. 3 | # 4 | # find $(Content) all MarkDown files | 5 | # jq -s -Rr -f phase2.jq 6 | # --arg DF "$$(find $(Data) -name '*.*')" 7 | # --arg Content $(Content) 8 | # --arg Data $(Data) 9 | # --arg Root $(Root) 10 | # --arg Meta $(Meta) 11 | # > $(Meta)/phase2.make 12 | 13 | # Extract pathname directory. 14 | def dir: 15 | if test("/") 16 | then sub("/[^/]+$"; "/") 17 | else "./" end 18 | ; 19 | 20 | # destination_paths := _site/jqt/ _site/jqt/blog/ ... 21 | def destination_paths($paths): 22 | def dpath: 23 | sub("^" + $Content; $Root) 24 | ; 25 | "destination_paths := " + ([$paths[] | dpath] | join(" ")) + "\n" 26 | ; 27 | 28 | # metadata_paths := .meta/pages/ .meta/pages/blog/ ... 29 | def metadata_paths($paths): 30 | def mpath: 31 | sub("^" + $Content; $Meta + "/pages") 32 | ; 33 | "metadata_paths := " + ([$paths[] | mpath] | join(" ")) + "\n" 34 | ; 35 | 36 | # data_md := .meta/snippets.json 37 | # data_yaml := 38 | # data_json := 39 | # data_csv := 40 | def data_files($files): 41 | def d2m($x): 42 | sub("\\."+$x+"$"; ".json") 43 | | sub("^"+$Data; $Meta) 44 | ; 45 | ($files / "\n") as $names 46 | | [$names[] | select(test(".md$"))] as $data_md 47 | | [$names[] | select(test(".yaml$"))] as $data_yaml 48 | | [$names[] | select(test(".json$"))] as $data_json 49 | | [$names[] | select(test(".csv$"))] as $data_csv 50 | | if ($data_md|length) == 0 then "data_md :=\n" 51 | else "data_md := " + ($data_md | map(d2m("md")) | join(" ")) + "\n" end 52 | + if ($data_yaml|length) == 0 then "data_yaml :=\n" 53 | else "data_yaml := " + ($data_yaml | map(d2m("yaml")) | join(" ")) + "\n" end 54 | + if ($data_json|length) == 0 then "data_json :=\n" 55 | else "data_json := " + ($data_json | map(d2m("json")) | join(" ")) + "\n" end 56 | + if ($data_csv|length) == 0 then "data_csv :=\n" 57 | else "data_csv := " + ($data_csv | map(d2m("csv")) | join(" ")) + "\n" end 58 | ; 59 | 60 | # PagesHTML := _site/jqt/content.html _site/jqt/blog/2017-04-13-hello.html ... 61 | def pages_html($documents): 62 | def dpage: 63 | sub("^" + $Content; $Root) 64 | | sub("\\.(?:markdown|mk?d)$"; ".html") 65 | ; 66 | "PagesHTML := " + ([$documents[] | dpage] | join(" ")) + "\n" 67 | ; 68 | 69 | # PagesJSON := .meta/pages/content.json .meta/pages/blog/2017-04-13-hello.json ... 70 | def md2json: 71 | sub("^" + $Content; $Meta + "/pages") 72 | | sub("\\.(?:markdown|mk?d)$"; ".json") 73 | ; 74 | 75 | def pages_json($documents): 76 | [$documents[] | md2json] as $json 77 | | "PagesJSON := " + ($json | join(" ")) + "\n" 78 | ; 79 | 80 | # .meta/pages/content.json: content/content.md 81 | # $(info ==> $@) 82 | # @$(EXTRACT_FRONT_MATTER) < $< | $(BUILD_PAGE_JSON) > $@ 83 | # ... 84 | # .meta/pages/blog/2017-04-13-hello.json: content/blog/2017-04-13-hello.md 85 | # $(info ==> $@) 86 | # @$(EXTRACT_FRONT_MATTER) < $< | $(BUILD_PAGE_JSON) > $@ 87 | def pages_json_rules($documents): 88 | [ $documents[] 89 | | md2json + ": " + . + "\n" + 90 | "\t$(info ==> $@)\n" + 91 | "\t@$(EXTRACT_FRONT_MATTER) < $< | $(BUILD_PAGE_JSON) > $@" 92 | ] | join("\n") 93 | ; 94 | 95 | # 96 | # Output makefile 97 | # 98 | (.[:-1] / "\n") as $documents 99 | | ([$documents[] | dir] | unique) as $paths 100 | | 101 | "__phase_2 := 1\n", 102 | destination_paths($paths), 103 | metadata_paths($paths), 104 | data_files($DF), 105 | pages_html($documents), 106 | pages_json($documents), 107 | pages_json_rules($documents), 108 | "\n# \u0076im:syntax=make" 109 | 110 | # vim:ts=4:sw=4:ai:et:fileencoding=utf8:syntax=jq 111 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # _jqt_ · The _jq_ template engine 2 | 3 | _jqt_ is a web template engine that uses [_jq_](https://stedolan.github.io/jq/) as expression language. 4 | 5 | The tools used in the implementation of _jqt_ are: 6 | 7 | * [jq](https://stedolan.github.io/jq/), a lightweight and flexible command-line JSON processor. 8 | * [GPP](https://logological.org/gpp), a general-purpose preprocessor. 9 | * [Pandoc](http://pandoc.org/), a universal document converter. 10 | * [Bash](https://www.gnu.org/software/bash/), [sed](https://www.gnu.org/software/sed/) and other shell tools. 11 | 12 | If you want to learn how to use _jqt_ visit the site 13 | . The site pages are generated using _jqt_ in 14 | the [`docs`](./docs/) folder of this repository. 15 | If you are interested in _jqt_ you can see also [JBOL](https://github.com/fadado/jbol), 16 | a related project with a collection of modules for the _jq_ language. 17 | 18 | _jqt_ is developed under the _Fedora_ Linux distribution, and a lot of 19 | portability issues are expected at this stage of development. Please, use this 20 | GitHub repository features if you want to send any kind of questions. 21 | 22 | ## Project management 23 | 24 | This project uses [GNU Make](https://www.gnu.org/software/make/) on several 25 | development activities, but `make` is not necessary to run `jqt`. This section explains 26 | the repository structure and how it is managed. 27 | 28 | ### Makefile 29 | 30 | The file `Makefile` concentrates all the routine procedures, like running the tests 31 | or install last versions of scripts in the system directories. The main defined _targets_ 32 | are: 33 | 34 | * `list`: list all targets defined in the Makefile. 35 | 36 | * `check`: run the _jqt_ tests. This is the default target. 37 | 38 | * `clean`: remove all files generated during tests execution. 39 | 40 | * `install`: install _jqt_ scripts and related files in the system directories. 41 | 42 | * `uninstall`: remove installed files from the system directories. 43 | 44 | ### Installation 45 | 46 | In systems with the GNU software installed tools such as [Bash](https://www.gnu.org/software/bash/), 47 | [sed](https://www.gnu.org/software/sed/) and other shell tools are installed by default. 48 | To use _jqt_ you must install additional tools like [GPP](https://logological.org/gpp) 49 | or [Pandoc](http://pandoc.org/); for example, in recent _Fedora Linux_ distributions 50 | the following command will install all the extra software _jqt_ needs: 51 | 52 | ```zsh 53 | $ sudo dnf -y install make general-purpose-preprocessor jq pandoc python2-pyyaml 54 | ``` 55 | 56 | To install _jqt_ simply run `make install` on the _jqt_ repository top 57 | directory. If you don’t like to install into the `/usr/local` system directory you 58 | can change the destination directory: 59 | 60 | ```zsh 61 | $ sudo make install prefix=/your/installation/path 62 | ``` 63 | 64 | Alternatively you can install _jqt_ manually executing a few commands on the 65 | _jqt_ top directory: 66 | 67 | ```zsh 68 | $ sudo mkdir -p /usr/local/bin /usr/local/share/jqt 69 | $ sudo cp bin/* /usr/local/bin 70 | $ sudo cp -r share/* /usr/local/share/jqt 71 | $ [[ $PATH =~ /usr/local/bin ]] || echo 'Add /usr/local/bin to your PATH' 72 | ``` 73 | 74 | ### Scripts 75 | 76 | The `bin` directory contains `jqt` and other related tools. The `jqt` script 77 | also needs some files located in the [`share`](./share/) directory. 78 | 79 | ### Tests 80 | 81 | The execution of `make check` or simply `make` will run several tests located in the directory 82 | [`tests`](./tests/). Ensure that the tests are passed before start 83 | another `jqt` uses. 84 | 85 | ### Documentation 86 | 87 | The directory [`docs`](./docs/) contains the source files for _jqt_ 88 | documentation. Please see the directory [`docs`](./docs/) for all information 89 | on this subproject. 90 | 91 | 94 | -------------------------------------------------------------------------------- /tests/format/data/au.json: -------------------------------------------------------------------------------- 1 | { 2 | "city": "Bendick Murrell", 3 | "first_name": "Ena", 4 | "last_name": "Desjardiws", 5 | "web": "http://www.selsorrobertjesq.com.au", 6 | "phone2": "0415-961-606", 7 | "phone1": "02-5226-9402", 8 | "state": "NS", 9 | "company_name": "Selsor, Robert J Esq", 10 | "address": "60562 Ky Rt 321", 11 | "post": "2803", 12 | "email": "ena_desjardiws@desjardiws.com.au" 13 | } 14 | { 15 | "city": "Talmalmo", 16 | "first_name": "Gerardo", 17 | "last_name": "Woodka", 18 | "web": "http://www.morrisdowningsherred.com.au", 19 | "phone2": "0443-795-912", 20 | "phone1": "02-6044-4682", 21 | "state": "NS", 22 | "company_name": "Morris Downing & Sherred", 23 | "address": "69206 Jackson Ave", 24 | "post": "2640", 25 | "email": "gerardo_woodka@hotmail.com" 26 | } 27 | { 28 | "city": "Cartmeticup", 29 | "first_name": "Idella", 30 | "last_name": "Scotland", 31 | "web": "http://www.artesianicecoldstorageco.com.au", 32 | "phone2": "0451-966-921", 33 | "phone1": "08-7868-1355", 34 | "state": "WA", 35 | "company_name": "Artesian Ice & Cold Storage Co", 36 | "address": "373 Lafayette St", 37 | "post": "6316", 38 | "email": "idella@hotmail.com" 39 | } 40 | { 41 | "city": "Hamel", 42 | "first_name": "Mariko", 43 | "last_name": "Stayer", 44 | "web": "http://www.inabinetmacreesq.com.au", 45 | "phone2": "0427-885-282", 46 | "phone1": "08-5558-9019", 47 | "state": "WA", 48 | "company_name": "Inabinet, Macre Esq", 49 | "address": "534 Schoenborn St #51", 50 | "post": "6215", 51 | "email": "mariko_stayer@hotmail.com" 52 | } 53 | { 54 | "city": "Lane Cove", 55 | "first_name": "Mayra", 56 | "last_name": "Bena", 57 | "web": "http://www.bueltdavidlesq.com.au", 58 | "phone2": "0453-666-885", 59 | "phone1": "02-1455-6085", 60 | "state": "NS", 61 | "company_name": "Buelt, David L Esq", 62 | "address": "808 Glen Cove Ave", 63 | "post": "1595", 64 | "email": "mayra.bena@gmail.com" 65 | } 66 | { 67 | "city": "Leith", 68 | "first_name": "Rebbecca", 69 | "last_name": "Didio", 70 | "web": "http://www.brandtjonathanfesq.com.au", 71 | "phone2": "0458-665-290", 72 | "phone1": "03-8174-9123", 73 | "state": "TA", 74 | "company_name": "Brandt, Jonathan F Esq", 75 | "address": "171 E 24th St", 76 | "post": "7315", 77 | "email": "rebbecca.didio@didio.com.au" 78 | } 79 | { 80 | "city": "Nyamup", 81 | "first_name": "Sherill", 82 | "last_name": "Klar", 83 | "web": "http://www.midwayhotel.com.au", 84 | "phone2": "0427-991-688", 85 | "phone1": "08-6522-8931", 86 | "state": "WA", 87 | "company_name": "Midway Hotel", 88 | "address": "87 Sylvan Ave", 89 | "post": "6258", 90 | "email": "sklar@hotmail.com" 91 | } 92 | { 93 | "city": "Proston", 94 | "first_name": "Stevie", 95 | "last_name": "Hallo", 96 | "web": "http://www.landrumtemporaryservices.com.au", 97 | "phone2": "0497-622-620", 98 | "phone1": "07-9997-3366", 99 | "state": "QL", 100 | "company_name": "Landrum Temporary Services", 101 | "address": "22222 Acoma St", 102 | "post": "4613", 103 | "email": "stevie.hallo@hotmail.com" 104 | } 105 | { 106 | "city": "Blanchetown", 107 | "first_name": "Theron", 108 | "last_name": "Jarding", 109 | "web": "http://www.prentisspaulfesq.com.au", 110 | "phone2": "0461-862-457", 111 | "phone1": "08-6890-4661", 112 | "state": "SA", 113 | "company_name": "Prentiss, Paul F Esq", 114 | "address": "8839 Ventura Blvd", 115 | "post": "5357", 116 | "email": "tjarding@hotmail.com" 117 | } 118 | { 119 | "city": "Purrawunda", 120 | "first_name": "Vince", 121 | "last_name": "Siena", 122 | "web": "http://www.vincentjpettico.com.au", 123 | "phone2": "0411-732-965", 124 | "phone1": "07-3184-9989", 125 | "state": "QL", 126 | "company_name": "Vincent J Petti & Co", 127 | "address": "70 S 18th Pl", 128 | "post": "4356", 129 | "email": "vince_siena@yahoo.com" 130 | } 131 | -------------------------------------------------------------------------------- /share/sake.d/phase3.make: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # phase3.make -- Define standard rules and rules for HTML pages and nodes. 3 | # 4 | # Rules defined in $(Meta)/phase3.make: 5 | # all HTML target files 6 | # 7 | # Rules defined in $(MDIR)/phase3.make: 8 | # $(Meta)/phase3.make 9 | # $(Meta)/phase3_json.json 10 | # $(Meta)/phase3d.make 11 | 12 | SUPER := $(Meta)/phase2.make 13 | 14 | ######################################################################## 15 | # Create makefile containing rules for all HTML files. 16 | ######################################################################## 17 | 18 | # Build rules for each page. 19 | $(Meta)/phase3.make: $(SUPER) $(THIS) 20 | $(Meta)/phase3.make: $(Meta)/pages-by-id.json $(SCRIPT) 21 | $(info ==> $@) 22 | jq --raw-output \ 23 | --arg Meta $(Meta) \ 24 | --arg Layouts $(Layouts) \ 25 | --arg Root $(Root) \ 26 | --from-file $(MDIR)/phase3.jq \ 27 | < $< > $@ 28 | 29 | # Do not preserve! 30 | .INTERMEDIATE: $(Meta)/phase3_json.json 31 | 32 | $(Meta)/phase3_json.json: $(SCRIPT) $(THIS) 33 | $(info ==> $@) 34 | grep -r '<%include\s\+[^>]\+>' blocks/ layouts/\ 35 | | sed -e 's/:.*<%include\s\+/\t/;s/>.*$$//' \ 36 | | jq -nrR \ 37 | --arg Layouts $(Layouts) \ 38 | --from-file $(MDIR)/phase3_json.jq \ 39 | > $@ 40 | 41 | $(Meta)/phase3.make: $(SUPER) $(THIS) 42 | $(Meta)/phase3d.make: $(Meta)/pages-by-id.json $(Meta)/phase3_json.json $(SCRIPT) 43 | $(info ==> $@) 44 | jq --raw-output \ 45 | --arg Layouts $(Layouts) \ 46 | --arg Root $(Root) \ 47 | --slurpfile ldep $(Meta)/phase3_json.json \ 48 | --from-file $(MDIR)/phase3d.jq \ 49 | < $< > $@ 50 | 51 | ifdef __phase_3 52 | 53 | # 54 | # Variables used in `$(Meta)/phase3.make`. 55 | # 56 | 57 | define JQTFLAGS := 58 | -I./ \ 59 | -L$(Meta) \ 60 | -L$(Blocks) \ 61 | -jsite:phase1_site.json \ 62 | -jpages:pages-by-id.json \ 63 | -ifilters 64 | endef 65 | 66 | JQT = jqt $(JQTFLAGS) 67 | 68 | define DETAILS := 69 | sed -e 's/^

    <\/p>/
    /' \ 70 | -e 's/^

    <\/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 | --------------------------------------------------------------------------------