minimaJake 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/_includes/custom/anchor_headings.html +164 -0
- data/_includes/custom/contents.html +180 -0
- data/_includes/custom/donatebutton.html +1 -0
- data/_includes/custom/donatefloating.html +9 -0
- data/_includes/custom/paginator.html +145 -0
- data/_includes/custom/read_time.html +5 -0
- data/_includes/custom/search.html +57 -0
- data/_includes/custom/tags.html +6 -0
- data/_includes/footer.html +26 -0
- data/_includes/google-analytics.html +9 -0
- data/_includes/head.html +14 -0
- data/_includes/header.html +39 -0
- data/_includes/social/icons/code.svg +1 -0
- data/_includes/social/icons/devto.svg +1 -0
- data/_includes/social/icons/dribbble.svg +1 -0
- data/_includes/social/icons/email.svg +1 -0
- data/_includes/social/icons/facebook.svg +1 -0
- data/_includes/social/icons/flickr.svg +1 -0
- data/_includes/social/icons/github.svg +1 -0
- data/_includes/social/icons/gitlab.svg +1 -0
- data/_includes/social/icons/google_scholar.svg +1 -0
- data/_includes/social/icons/instagram.svg +1 -0
- data/_includes/social/icons/keybase.svg +4 -0
- data/_includes/social/icons/linkedin.svg +1 -0
- data/_includes/social/icons/mastodon.svg +1 -0
- data/_includes/social/icons/microdotblog.svg +1 -0
- data/_includes/social/icons/pinterest.svg +1 -0
- data/_includes/social/icons/rss.svg +1 -0
- data/_includes/social/icons/stackoverflow.svg +1 -0
- data/_includes/social/icons/substack.svg +1 -0
- data/_includes/social/icons/telegram.svg +1 -0
- data/_includes/social/icons/twitter.svg +1 -0
- data/_includes/social/icons/youtube.svg +1 -0
- data/_includes/social/meta-item.html +8 -0
- data/_includes/social/meta.html +7 -0
- data/_includes/social/social-item.html +7 -0
- data/_includes/social/social.html +7 -0
- data/_includes/social/svg_symbol.html +3 -0
- data/_layouts/default.html +20 -0
- data/_layouts/home.html +59 -0
- data/_layouts/page.html +16 -0
- data/_layouts/post.html +63 -0
- data/_sass/minima/_base.scss +281 -0
- data/_sass/minima/_layout.scss +341 -0
- data/_sass/minima/custom-styles.scss +2 -0
- data/_sass/minima/custom-variables.scss +1 -0
- data/_sass/minima/initialize.scss +50 -0
- data/_sass/minima/skins/auto.scss +361 -0
- data/_sass/minima/skins/classic.scss +5 -0
- data/_sass/minima/skins/dark.scss +5 -0
- data/_sass/minima/skins/solarized-dark.scss +5 -0
- data/_sass/minima/skins/solarized-light.scss +4 -0
- data/_sass/minima/skins/solarized.scss +201 -0
- data/assets/css/style.scss +194 -0
- data/assets/js/posts.json +15 -0
- data/assets/js/search.js +438 -0
- data/assets/minima-social-icons.liquid +15 -0
- metadata +165 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f8cf3f8c77fc7a0c7d98cb2544b3408e6a7af33be1acaf402152d37fabf9e98c
|
4
|
+
data.tar.gz: 90be3fa39a05be8351481b0be6974aea52679b01f788b847938e9b0f5d281574
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ab18af65dcf7d9189d512df0d68aec4ebd21a53e0d27dd67be4dca07f9509e12964448bc3365c731c8bd3ffecab319a4edea97fb4b99a4d2d958c681ce7f066a
|
7
|
+
data.tar.gz: a913529d59bfbfe5948753fe0884bb56d70fa90296a100db57d8bb887a097a581ce73243792079271dba52a9a3f2957e4818d4224ff62c8ac9698942e0015f3a
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016-present Parker Moore and the minima contributors
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# minimaJake
|
2
|
+
|
3
|
+
This project is a fork of the default [minima theme](https://github.com/jekyll/minima) that [Jekyll](https://github.com/jekyll/jekyll) uses, aiming to add enough functionality to make minima a realistic choice, without any bloat / nonsense.
|
4
|
+
|
5
|
+
## About
|
6
|
+
|
7
|
+
minimaJake is used to host [JakeSteam](https://github.com/JakeSteam)'s [personal](https://jakelee.co.uk), [programming](https://blog.jakelee.co.uk), and [internet history](https://history.jakelee.co.uk) sites.
|
8
|
+
|
9
|
+
A live demo is available at [minima.jakelee.co.uk](https://minima.jakelee.co.uk), and a full guide to all features is available in [the announcement post](https://blog.jakelee.co.uk/introducing-minimajake-for-jekyll/).
|
10
|
+
|
11
|
+
## How to use
|
12
|
+
|
13
|
+
The easiest way is to just [copy the `_config.yml`](https://github.com/JakeSteam/blog-programming/blob/main/_config.yml) from one of the blogs using this theme, updating the name / accent colour etc as desired.
|
14
|
+
|
15
|
+
The theme is imported via `remote_theme: JakeSteam/minimaJake`, optionally adding `@1.0.2` to specify a release from [the releases page](https://github.com/JakeSteam/minimaJake/releases).
|
16
|
+
|
17
|
+
## Additions
|
18
|
+
|
19
|
+
Native (liquid) features:
|
20
|
+
|
21
|
+
* Table of contents
|
22
|
+
* Linkable headers
|
23
|
+
* Tag system
|
24
|
+
* Pagination improvements
|
25
|
+
* End of post call to action
|
26
|
+
* Social & meta link system in footer
|
27
|
+
* Network site picker
|
28
|
+
|
29
|
+
Third party features:
|
30
|
+
|
31
|
+
* Search
|
32
|
+
* Giscus comments
|
33
|
+
* Configurable Ko-fi donation button & floating prompt
|
34
|
+
|
35
|
+
Design changes:
|
36
|
+
|
37
|
+
* Banner images
|
38
|
+
* Accent colour system
|
39
|
+
|
40
|
+
[![](https://blog.jakelee.co.uk/assets/images/2023/minimajake.png)](https://blog.jakelee.co.uk/assets/images/2023/minimajake.png)
|
41
|
+
|
@@ -0,0 +1,164 @@
|
|
1
|
+
{% capture headingsWorkspace %}
|
2
|
+
{% comment %}
|
3
|
+
Copyright (c) 2018 Vladimir "allejo" Jimenez
|
4
|
+
Permission is hereby granted, free of charge, to any person
|
5
|
+
obtaining a copy of this software and associated documentation
|
6
|
+
files (the "Software"), to deal in the Software without
|
7
|
+
restriction, including without limitation the rights to use,
|
8
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the
|
10
|
+
Software is furnished to do so, subject to the following
|
11
|
+
conditions:
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
16
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
18
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
19
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
20
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
21
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
{% endcomment %}
|
23
|
+
{% comment %}
|
24
|
+
Version 1.0.11
|
25
|
+
https://github.com/allejo/jekyll-anchor-headings
|
26
|
+
"Be the pull request you wish to see in the world." ~Ben Balter
|
27
|
+
Usage:
|
28
|
+
{% include anchor_headings.html html=content anchorBody="#" %}
|
29
|
+
Parameters:
|
30
|
+
* html (string) - the HTML of compiled markdown generated by kramdown in Jekyll
|
31
|
+
Optional Parameters:
|
32
|
+
* beforeHeading (bool) : false - Set to true if the anchor should be placed _before_ the heading's content
|
33
|
+
* headerAttrs (string) : '' - Any custom HTML attributes that will be added to the heading tag; you may NOT use `id`;
|
34
|
+
the `%heading%` and `%html_id%` placeholders are available
|
35
|
+
* anchorAttrs (string) : '' - Any custom HTML attributes that will be added to the `<a>` tag; you may NOT use `href`, `class` or `title`;
|
36
|
+
the `%heading%` and `%html_id%` placeholders are available
|
37
|
+
* anchorBody (string) : '' - The content that will be placed inside the anchor; the `%heading%` placeholder is available
|
38
|
+
* anchorClass (string) : '' - The class(es) that will be used for each anchor. Separate multiple classes with a space
|
39
|
+
* anchorTitle (string) : '' - The `title` attribute that will be used for anchors
|
40
|
+
* h_min (int) : 1 - The minimum header level to build an anchor for; any header lower than this value will be ignored
|
41
|
+
* h_max (int) : 6 - The maximum header level to build an anchor for; any header greater than this value will be ignored
|
42
|
+
* bodyPrefix (string) : '' - Anything that should be inserted inside of the heading tag _before_ its anchor and content
|
43
|
+
* bodySuffix (string) : '' - Anything that should be inserted inside of the heading tag _after_ its anchor and content
|
44
|
+
* generateId (true) : false - Set to true if a header without id should generate an id to use.
|
45
|
+
Output:
|
46
|
+
The original HTML with the addition of anchors inside of all of the h1-h6 headings.
|
47
|
+
{% endcomment %}
|
48
|
+
|
49
|
+
{% assign minHeader = include.h_min | default: 1 %}
|
50
|
+
{% assign maxHeader = include.h_max | default: 6 %}
|
51
|
+
{% assign beforeHeading = include.beforeHeading %}
|
52
|
+
{% assign headerAttrs = include.headerAttrs %}
|
53
|
+
{% assign nodes = include.html | split: '<h' %}
|
54
|
+
|
55
|
+
{% capture edited_headings %}{% endcapture %}
|
56
|
+
|
57
|
+
{% for _node in nodes %}
|
58
|
+
{% capture node %}{{ _node | strip }}{% endcapture %}
|
59
|
+
|
60
|
+
{% if node == "" %}
|
61
|
+
{% continue %}
|
62
|
+
{% endif %}
|
63
|
+
|
64
|
+
{% assign nextChar = node | replace: '"', '' | strip | slice: 0, 1 %}
|
65
|
+
{% assign headerLevel = nextChar | times: 1 %}
|
66
|
+
|
67
|
+
<!-- If the level is cast to 0, it means it's not a h1-h6 tag, so let's see if we need to fix it -->
|
68
|
+
{% if headerLevel == 0 %}
|
69
|
+
<!-- Split up the node based on closing angle brackets and get the first one. -->
|
70
|
+
{% assign firstChunk = node | split: '>' | first %}
|
71
|
+
|
72
|
+
<!-- If the first chunk does NOT contain a '<', that means we've broken another HTML tag that starts with 'h' -->
|
73
|
+
{% unless firstChunk contains '<' %}
|
74
|
+
{% capture node %}<h{{ node }}{% endcapture %}
|
75
|
+
{% endunless %}
|
76
|
+
|
77
|
+
{% capture edited_headings %}{{ edited_headings }}{{ node }}{% endcapture %}
|
78
|
+
{% continue %}
|
79
|
+
{% endif %}
|
80
|
+
|
81
|
+
{% capture _closingTag %}</h{{ headerLevel }}>{% endcapture %}
|
82
|
+
{% assign _workspace = node | split: _closingTag %}
|
83
|
+
{% capture _hAttrToStrip %}{{ _workspace[0] | split: '>' | first }}>{% endcapture %}
|
84
|
+
{% assign header = _workspace[0] | replace: _hAttrToStrip, '' %}
|
85
|
+
{% assign escaped_header = header | strip_html | strip %}
|
86
|
+
|
87
|
+
{% assign _classWorkspace = _workspace[0] | split: 'class="' %}
|
88
|
+
{% assign _classWorkspace = _classWorkspace[1] | split: '"' %}
|
89
|
+
{% assign _html_class = _classWorkspace[0] %}
|
90
|
+
|
91
|
+
{% if _html_class contains "no_anchor" %}
|
92
|
+
{% assign skip_anchor = true %}
|
93
|
+
{% else %}
|
94
|
+
{% assign skip_anchor = false %}
|
95
|
+
{% endif %}
|
96
|
+
|
97
|
+
{% assign _idWorkspace = _workspace[0] | split: 'id="' %}
|
98
|
+
{% if _idWorkspace[1] %}
|
99
|
+
{% assign _idWorkspace = _idWorkspace[1] | split: '"' %}
|
100
|
+
{% assign html_id = _idWorkspace[0] %}
|
101
|
+
{% elsif include.generateId %}
|
102
|
+
<!-- If the header did not have an id we create one. -->
|
103
|
+
{% assign html_id = escaped_header | slugify %}
|
104
|
+
{% if html_id == "" %}
|
105
|
+
{% assign html_id = false %}
|
106
|
+
{% endif %}
|
107
|
+
{% capture headerAttrs %}{{ headerAttrs }} id="%html_id%"{% endcapture %}
|
108
|
+
{% endif %}
|
109
|
+
|
110
|
+
<!-- Build the anchor to inject for our heading -->
|
111
|
+
{% capture anchor %}{% endcapture %}
|
112
|
+
|
113
|
+
{% if skip_anchor == false and html_id and headerLevel >= minHeader and headerLevel <= maxHeader %}
|
114
|
+
{% if headerAttrs %}
|
115
|
+
{% capture _hAttrToStrip %}{{ _hAttrToStrip | split: '>' | first }} {{ headerAttrs | replace: '%heading%', escaped_header | replace: '%html_id%', html_id }}>{% endcapture %}
|
116
|
+
{% endif %}
|
117
|
+
|
118
|
+
{% capture anchor %}href="#{{ html_id }}"{% endcapture %}
|
119
|
+
|
120
|
+
{% if include.anchorClass %}
|
121
|
+
{% capture anchor %}{{ anchor }} class="{{ include.anchorClass }}"{% endcapture %}
|
122
|
+
{% endif %}
|
123
|
+
|
124
|
+
{% if include.anchorTitle %}
|
125
|
+
{% capture anchor %}{{ anchor }} title="{{ include.anchorTitle | replace: '%heading%', escaped_header }}"{% endcapture %}
|
126
|
+
{% endif %}
|
127
|
+
|
128
|
+
{% if include.anchorAttrs %}
|
129
|
+
{% capture anchor %}{{ anchor }} {{ include.anchorAttrs | replace: '%heading%', escaped_header | replace: '%html_id%', html_id }}{% endcapture %}
|
130
|
+
{% endif %}
|
131
|
+
|
132
|
+
{% capture anchor %}<a {{ anchor }}>{{ include.anchorBody | replace: '%heading%', escaped_header | default: '' }}</a>{% endcapture %}
|
133
|
+
|
134
|
+
<!-- In order to prevent adding extra space after a heading, we'll let the 'anchor' value contain it -->
|
135
|
+
{% if beforeHeading %}
|
136
|
+
{% capture anchor %}{{ anchor }} {% endcapture %}
|
137
|
+
{% else %}
|
138
|
+
{% capture anchor %} {{ anchor }}{% endcapture %}
|
139
|
+
{% endif %}
|
140
|
+
{% endif %}
|
141
|
+
|
142
|
+
{% capture new_heading %}
|
143
|
+
<h{{ _hAttrToStrip }}
|
144
|
+
{{ include.bodyPrefix }}
|
145
|
+
{% if beforeHeading %}
|
146
|
+
{{ anchor }}{{ header }}
|
147
|
+
{% else %}
|
148
|
+
{{ header }}{{ anchor }}
|
149
|
+
{% endif %}
|
150
|
+
{{ include.bodySuffix }}
|
151
|
+
</h{{ headerLevel }}>
|
152
|
+
{% endcapture %}
|
153
|
+
|
154
|
+
<!--
|
155
|
+
If we have content after the `</hX>` tag, then we'll want to append that here so we don't lost any content.
|
156
|
+
-->
|
157
|
+
{% assign chunkCount = _workspace | size %}
|
158
|
+
{% if chunkCount > 1 %}
|
159
|
+
{% capture new_heading %}{{ new_heading }}{{ _workspace | last }}{% endcapture %}
|
160
|
+
{% endif %}
|
161
|
+
|
162
|
+
{% capture edited_headings %}{{ edited_headings }}{{ new_heading }}{% endcapture %}
|
163
|
+
{% endfor %}
|
164
|
+
{% endcapture %}{% assign headingsWorkspace = '' %}{{ edited_headings | strip }}
|
@@ -0,0 +1,180 @@
|
|
1
|
+
{% capture tocWorkspace %}
|
2
|
+
{% comment %}
|
3
|
+
Copyright (c) 2017 Vladimir "allejo" Jimenez
|
4
|
+
Permission is hereby granted, free of charge, to any person
|
5
|
+
obtaining a copy of this software and associated documentation
|
6
|
+
files (the "Software"), to deal in the Software without
|
7
|
+
restriction, including without limitation the rights to use,
|
8
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the
|
10
|
+
Software is furnished to do so, subject to the following
|
11
|
+
conditions:
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
16
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
18
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
19
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
20
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
21
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
{% endcomment %}
|
23
|
+
{% comment %}
|
24
|
+
Version 1.2.0
|
25
|
+
https://github.com/allejo/jekyll-toc
|
26
|
+
"...like all things liquid - where there's a will, and ~36 hours to spare, there's usually a/some way" ~jaybe
|
27
|
+
Usage:
|
28
|
+
{% include toc.html html=content sanitize=true class="inline_toc" id="my_toc" h_min=2 h_max=3 %}
|
29
|
+
Parameters:
|
30
|
+
* html (string) - the HTML of compiled markdown generated by kramdown in Jekyll
|
31
|
+
Optional Parameters:
|
32
|
+
* sanitize (bool) : false - when set to true, the headers will be stripped of any HTML in the TOC
|
33
|
+
* class (string) : '' - a CSS class assigned to the TOC
|
34
|
+
* id (string) : '' - an ID to assigned to the TOC
|
35
|
+
* h_min (int) : 1 - the minimum TOC header level to use; any header lower than this value will be ignored
|
36
|
+
* h_max (int) : 6 - the maximum TOC header level to use; any header greater than this value will be ignored
|
37
|
+
* ordered (bool) : false - when set to true, an ordered list will be outputted instead of an unordered list
|
38
|
+
* item_class (string) : '' - add custom class(es) for each list item; has support for '%level%' placeholder, which is the current heading level
|
39
|
+
* submenu_class (string) : '' - add custom class(es) for each child group of headings; has support for '%level%' placeholder which is the current "submenu" heading level
|
40
|
+
* base_url (string) : '' - add a base url to the TOC links for when your TOC is on another page than the actual content
|
41
|
+
* anchor_class (string) : '' - add custom class(es) for each anchor element
|
42
|
+
* skip_no_ids (bool) : false - skip headers that do not have an `id` attribute
|
43
|
+
Output:
|
44
|
+
An ordered or unordered list representing the table of contents of a markdown block. This snippet will only
|
45
|
+
generate the table of contents and will NOT output the markdown given to it
|
46
|
+
{% endcomment %}
|
47
|
+
|
48
|
+
{% capture newline %}
|
49
|
+
{% endcapture %}
|
50
|
+
{% assign newline = newline | rstrip %} <!-- Remove the extra spacing but preserve the newline -->
|
51
|
+
|
52
|
+
{% capture deprecation_warnings %}{% endcapture %}
|
53
|
+
|
54
|
+
{% if include.baseurl %}
|
55
|
+
{% capture deprecation_warnings %}{{ deprecation_warnings }}<!-- jekyll-toc :: "baseurl" has been deprecated, use "base_url" instead -->{{ newline }}{% endcapture %}
|
56
|
+
{% endif %}
|
57
|
+
|
58
|
+
{% if include.skipNoIDs %}
|
59
|
+
{% capture deprecation_warnings %}{{ deprecation_warnings }}<!-- jekyll-toc :: "skipNoIDs" has been deprecated, use "skip_no_ids" instead -->{{ newline }}{% endcapture %}
|
60
|
+
{% endif %}
|
61
|
+
|
62
|
+
{% capture jekyll_toc %}{% endcapture %}
|
63
|
+
{% assign orderedList = include.ordered | default: false %}
|
64
|
+
{% assign baseURL = include.base_url | default: include.baseurl | default: '' %}
|
65
|
+
{% assign skipNoIDs = include.skip_no_ids | default: include.skipNoIDs | default: false %}
|
66
|
+
{% assign minHeader = include.h_min | default: 1 %}
|
67
|
+
{% assign maxHeader = include.h_max | default: 6 %}
|
68
|
+
{% assign nodes = include.html | strip | split: '<h' %}
|
69
|
+
|
70
|
+
{% assign firstHeader = true %}
|
71
|
+
{% assign currLevel = 0 %}
|
72
|
+
{% assign lastLevel = 0 %}
|
73
|
+
|
74
|
+
{% capture listModifier %}{% if orderedList %}ol{% else %}ul{% endif %}{% endcapture %}
|
75
|
+
|
76
|
+
{% for node in nodes %}
|
77
|
+
{% if node == "" %}
|
78
|
+
{% continue %}
|
79
|
+
{% endif %}
|
80
|
+
|
81
|
+
{% assign currLevel = node | replace: '"', '' | slice: 0, 1 | times: 1 %}
|
82
|
+
|
83
|
+
{% if currLevel < minHeader or currLevel > maxHeader %}
|
84
|
+
{% continue %}
|
85
|
+
{% endif %}
|
86
|
+
|
87
|
+
{% assign _workspace = node | split: '</h' %}
|
88
|
+
|
89
|
+
{% assign _idWorkspace = _workspace[0] | split: 'id="' %}
|
90
|
+
{% assign _idWorkspace = _idWorkspace[1] | split: '"' %}
|
91
|
+
{% assign htmlID = _idWorkspace[0] %}
|
92
|
+
|
93
|
+
{% assign _classWorkspace = _workspace[0] | split: 'class="' %}
|
94
|
+
{% assign _classWorkspace = _classWorkspace[1] | split: '"' %}
|
95
|
+
{% assign htmlClass = _classWorkspace[0] %}
|
96
|
+
|
97
|
+
{% if htmlClass contains "no_toc" %}
|
98
|
+
{% continue %}
|
99
|
+
{% endif %}
|
100
|
+
|
101
|
+
{% if firstHeader %}
|
102
|
+
{% assign minHeader = currLevel %}
|
103
|
+
{% endif %}
|
104
|
+
|
105
|
+
{% capture _hAttrToStrip %}{{ _workspace[0] | split: '>' | first }}>{% endcapture %}
|
106
|
+
{% assign header = _workspace[0] | replace: _hAttrToStrip, '' %}
|
107
|
+
|
108
|
+
{% if include.item_class and include.item_class != blank %}
|
109
|
+
{% capture listItemClass %} class="{{ include.item_class | replace: '%level%', currLevel | split: '.' | join: ' ' }}"{% endcapture %}
|
110
|
+
{% endif %}
|
111
|
+
|
112
|
+
{% if include.submenu_class and include.submenu_class != blank %}
|
113
|
+
{% assign subMenuLevel = currLevel | minus: 1 %}
|
114
|
+
{% capture subMenuClass %} class="{{ include.submenu_class | replace: '%level%', subMenuLevel | split: '.' | join: ' ' }}"{% endcapture %}
|
115
|
+
{% endif %}
|
116
|
+
|
117
|
+
{% capture anchorBody %}{% if include.sanitize %}{{ header | strip_html }}{% else %}{{ header }}{% endif %}{% endcapture %}
|
118
|
+
|
119
|
+
{% if htmlID %}
|
120
|
+
{% capture anchorAttributes %} href="{% if baseURL %}{{ baseURL }}{% endif %}#{{ htmlID }}"{% endcapture %}
|
121
|
+
|
122
|
+
{% if include.anchor_class %}
|
123
|
+
{% capture anchorAttributes %}{{ anchorAttributes }} class="{{ include.anchor_class | split: '.' | join: ' ' }}"{% endcapture %}
|
124
|
+
{% endif %}
|
125
|
+
|
126
|
+
{% capture listItem %}<a{{ anchorAttributes }}>{{ anchorBody }}</a>{% endcapture %}
|
127
|
+
{% elsif skipNoIDs == true %}
|
128
|
+
{% continue %}
|
129
|
+
{% else %}
|
130
|
+
{% capture listItem %}{{ anchorBody }}{% endcapture %}
|
131
|
+
{% endif %}
|
132
|
+
|
133
|
+
{% if currLevel > lastLevel %}
|
134
|
+
{% capture jekyll_toc %}{{ jekyll_toc }}<{{ listModifier }}{{ subMenuClass }}>{% endcapture %}
|
135
|
+
{% elsif currLevel < lastLevel %}
|
136
|
+
{% assign repeatCount = lastLevel | minus: currLevel %}
|
137
|
+
|
138
|
+
{% for i in (1..repeatCount) %}
|
139
|
+
{% capture jekyll_toc %}{{ jekyll_toc }}</li></{{ listModifier }}>{% endcapture %}
|
140
|
+
{% endfor %}
|
141
|
+
|
142
|
+
{% capture jekyll_toc %}{{ jekyll_toc }}</li>{% endcapture %}
|
143
|
+
{% else %}
|
144
|
+
{% capture jekyll_toc %}{{ jekyll_toc }}</li>{% endcapture %}
|
145
|
+
{% endif %}
|
146
|
+
|
147
|
+
{% capture jekyll_toc %}{{ jekyll_toc }}<li{{ listItemClass }}>{{ listItem }}{% endcapture %}
|
148
|
+
|
149
|
+
{% assign lastLevel = currLevel %}
|
150
|
+
{% assign firstHeader = false %}
|
151
|
+
{% endfor %}
|
152
|
+
|
153
|
+
{% assign repeatCount = minHeader | minus: 1 %}
|
154
|
+
{% assign repeatCount = lastLevel | minus: repeatCount %}
|
155
|
+
{% for i in (1..repeatCount) %}
|
156
|
+
{% capture jekyll_toc %}{{ jekyll_toc }}</li></{{ listModifier }}>{% endcapture %}
|
157
|
+
{% endfor %}
|
158
|
+
|
159
|
+
{% if jekyll_toc != '' %}
|
160
|
+
{% assign rootAttributes = '' %}
|
161
|
+
{% if include.class and include.class != blank %}
|
162
|
+
{% capture rootAttributes %} class="{{ include.class | split: '.' | join: ' ' }}"{% endcapture %}
|
163
|
+
{% endif %}
|
164
|
+
|
165
|
+
{% if include.id and include.id != blank %}
|
166
|
+
{% capture rootAttributes %}{{ rootAttributes }} id="{{ include.id }}"{% endcapture %}
|
167
|
+
{% endif %}
|
168
|
+
|
169
|
+
{% if rootAttributes %}
|
170
|
+
{% assign nodes = jekyll_toc | split: '>' %}
|
171
|
+
{% capture jekyll_toc %}
|
172
|
+
<div class="toc">
|
173
|
+
<b>{{ site.table_of_contents_header }}</b>
|
174
|
+
<{{ listModifier }}{{ rootAttributes }}>{{ nodes | shift | join: '>' }}>
|
175
|
+
</div>
|
176
|
+
{% endcapture %}
|
177
|
+
{% endif %}
|
178
|
+
{% endif %}
|
179
|
+
|
180
|
+
{% endcapture %}{% assign tocWorkspace = '' %}{{ deprecation_warnings }}{{ jekyll_toc -}}
|
@@ -0,0 +1 @@
|
|
1
|
+
<script type='text/javascript' src='https://storage.ko-fi.com/cdn/widget/Widget_2.js'></script><script type='text/javascript'>kofiwidget2.init('{{ site.kofi_button_text }}', '{{ site.accent_colour }}', '{{ site.kofi_id }}');kofiwidget2.draw();</script>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<script src='https://storage.ko-fi.com/cdn/scripts/overlay-widget.js'></script>
|
2
|
+
<script>
|
3
|
+
kofiWidgetOverlay.draw('{{ site.kofi_id }}', {
|
4
|
+
'type': 'floating-chat',
|
5
|
+
'floating-chat.donateButton.text': '{{ site.kofi_floating_text }}',
|
6
|
+
'floating-chat.donateButton.background-color': '{{ site.accent_colour }}',
|
7
|
+
'floating-chat.donateButton.text-color': '#fff'
|
8
|
+
});
|
9
|
+
</script>
|
@@ -0,0 +1,145 @@
|
|
1
|
+
{% capture spaceless %}
|
2
|
+
|
3
|
+
{% comment %}
|
4
|
+
Pagination links
|
5
|
+
* https://glennmccomb.com/articles/how-to-build-custom-hugo-pagination/
|
6
|
+
{% endcomment %}
|
7
|
+
|
8
|
+
{% if page.paginate_root == nil %}
|
9
|
+
{% assign paginate_root = "/" %}
|
10
|
+
{% else %}
|
11
|
+
{% assign paginate_root = page.paginate_root %}
|
12
|
+
{% endif %}
|
13
|
+
|
14
|
+
{% assign total_pages = paginator.total_pages %}
|
15
|
+
{% assign page_current = paginator.page %}
|
16
|
+
|
17
|
+
{% assign link_offset = 2 %}
|
18
|
+
{% assign link_max = link_offset | times: 2 | plus: 1 %}
|
19
|
+
|
20
|
+
{% assign limit_lower = link_offset | plus: 1 %}
|
21
|
+
{% assign limit_upper = total_pages | minus: link_offset %}
|
22
|
+
|
23
|
+
{% assign min_lower = link_max %}
|
24
|
+
{% assign max_upper = total_pages | minus: link_max %}
|
25
|
+
|
26
|
+
{% assign lower_offset = page_current | minus: link_offset %}
|
27
|
+
{% assign upper_offset = page_current | plus: link_offset %}
|
28
|
+
|
29
|
+
{% assign lower_indicator = 2 %}
|
30
|
+
{% assign upper_indicator = total_pages | minus: 1 %}
|
31
|
+
|
32
|
+
{% endcapture %}
|
33
|
+
|
34
|
+
<nav aria-label="Page navigation">
|
35
|
+
|
36
|
+
{% if total_pages > 1 %}
|
37
|
+
<div class="pagination justify-content-center">
|
38
|
+
<!-- Previous Page. -->
|
39
|
+
{% if paginator.previous_page %}
|
40
|
+
<span class="page-item blog_previous">
|
41
|
+
<a class="page-link"
|
42
|
+
href="{{ paginator.previous_page_path }}"
|
43
|
+
rel="prev">« Previous</a>
|
44
|
+
</span>
|
45
|
+
{% endif %}
|
46
|
+
|
47
|
+
{% if total_pages > link_max %}
|
48
|
+
<!-- First Page. -->
|
49
|
+
{% if lower_offset > 1 %}
|
50
|
+
<span class="page-item first">
|
51
|
+
<a class="page-link"
|
52
|
+
href="/">1</a>
|
53
|
+
</span>
|
54
|
+
{% endif %}
|
55
|
+
|
56
|
+
<!-- Early (More Pages) Indicator. -->
|
57
|
+
{% if lower_offset > lower_indicator %}
|
58
|
+
<span class="pages-indicator first disabled">
|
59
|
+
<span class="page-link">...</span>
|
60
|
+
</span>
|
61
|
+
{% endif %}
|
62
|
+
{% endif %}
|
63
|
+
|
64
|
+
<!-- Page numbers. -->
|
65
|
+
{% for page in (1..total_pages) %}
|
66
|
+
|
67
|
+
{% capture spaceless %}
|
68
|
+
{% assign page_current_flag = false %}
|
69
|
+
|
70
|
+
{% if total_pages > link_max %}
|
71
|
+
|
72
|
+
{% if page_current <= limit_lower %}
|
73
|
+
{% if page <= min_lower %}
|
74
|
+
{% assign page_current_flag = true %}
|
75
|
+
{% endif %}
|
76
|
+
|
77
|
+
{% elsif page_current >= limit_upper %}
|
78
|
+
{% if page > max_upper %}
|
79
|
+
{% assign page_current_flag = true %}
|
80
|
+
{% endif %}
|
81
|
+
|
82
|
+
{% else %}
|
83
|
+
|
84
|
+
{% if (page >= lower_offset) and (page <= upper_offset) %}
|
85
|
+
{% assign page_current_flag = true %}
|
86
|
+
{% endif %}
|
87
|
+
|
88
|
+
{% endif %}
|
89
|
+
|
90
|
+
{% else %}
|
91
|
+
|
92
|
+
{% assign page_current_flag = true %}
|
93
|
+
{% endif %}
|
94
|
+
{% endcapture %}
|
95
|
+
|
96
|
+
<!-- Show Pager. -->
|
97
|
+
{% if page_current_flag == true %}
|
98
|
+
<span class="page-item {% if page == page_current %} active{% endif %}">
|
99
|
+
{% if page == page_current %}
|
100
|
+
<span class="page-link">
|
101
|
+
{{ page }}
|
102
|
+
</span>
|
103
|
+
{% elsif page == 1 %}
|
104
|
+
<a class="page-link"
|
105
|
+
href="/"
|
106
|
+
>1</a>
|
107
|
+
{% else %}
|
108
|
+
<a class="page-link"
|
109
|
+
href="{{ site.paginate_path | relative_url | replace: ':num', page }}"
|
110
|
+
>{{ page }}</a>
|
111
|
+
{% endif %}
|
112
|
+
</span>
|
113
|
+
{% endif %}
|
114
|
+
{% endfor %}
|
115
|
+
|
116
|
+
{% if total_pages > link_max %}
|
117
|
+
<!-- Late (More Pages) Indicator. -->
|
118
|
+
{% if upper_offset < upper_indicator %}
|
119
|
+
<span class="pages-indicator last disabled">
|
120
|
+
<span class="page-link">...</span>
|
121
|
+
</span>
|
122
|
+
{% endif %}
|
123
|
+
|
124
|
+
<!-- Last Page. -->
|
125
|
+
{% if upper_offset < total_pages %}
|
126
|
+
<span class="page-item last">
|
127
|
+
<a class="page-link"
|
128
|
+
href="{{ site.paginate_path | relative_url | replace: ':num', total_pages }}"
|
129
|
+
>{{ total_pages }}</a>
|
130
|
+
</span>
|
131
|
+
{% endif %}
|
132
|
+
{% endif %}
|
133
|
+
|
134
|
+
<!-- Next Page. -->
|
135
|
+
{% if paginator.next_page %}
|
136
|
+
<span class="page-item blog_next">
|
137
|
+
<a class="page-link"
|
138
|
+
href="{{ paginator.next_page_path }}"
|
139
|
+
rel="next">Next »</a>
|
140
|
+
</span>
|
141
|
+
{% endif %}
|
142
|
+
</div>
|
143
|
+
{% endif %}
|
144
|
+
|
145
|
+
</nav>
|
@@ -0,0 +1,57 @@
|
|
1
|
+
<form id="searchform">
|
2
|
+
<p><input type="text" id="search-input" class="form-control" name="q" value="" autofocus /></p>
|
3
|
+
</form>
|
4
|
+
<ul id="searchresults" class="post-list"></ul>
|
5
|
+
|
6
|
+
<script src="/assets/js/search.js" type="text/javascript"></script>
|
7
|
+
|
8
|
+
<script>
|
9
|
+
var sjs = SimpleJekyllSearch({
|
10
|
+
searchInput: document.getElementById('searchform'),
|
11
|
+
resultsContainer: document.getElementById('searchresults'),
|
12
|
+
json: '/assets/js/posts.json',
|
13
|
+
templateMiddleware: function(prop, value, template) {
|
14
|
+
if (prop === "title" || prop === "excerpt") {
|
15
|
+
value = value.replace(/&/g, "&");
|
16
|
+
}
|
17
|
+
return value.replace(
|
18
|
+
new RegExp(document.getElementById('search-input').value, "gi"),
|
19
|
+
'<span class="highlight">$&</span>'
|
20
|
+
)
|
21
|
+
},
|
22
|
+
sortMiddleware: function(a, b) {
|
23
|
+
aPrio = matchPriority(a.matchedField)
|
24
|
+
bPrio = matchPriority(b.matchedField)
|
25
|
+
return bPrio - aPrio
|
26
|
+
},
|
27
|
+
searchResultTemplate: "<li class='card'>" +
|
28
|
+
"<div class='content'>" +
|
29
|
+
"<a class='post-link' href='{url}'>{title}</a>" +
|
30
|
+
"<span class='post-meta'>{date} • {tags}</span>" +
|
31
|
+
"<p>{excerpt}</p>" +
|
32
|
+
"</div>" +
|
33
|
+
"</li>"
|
34
|
+
})
|
35
|
+
|
36
|
+
function matchPriority (fieldMatched) {
|
37
|
+
switch (fieldMatched) {
|
38
|
+
case 'tags':
|
39
|
+
return 5;
|
40
|
+
case 'title':
|
41
|
+
return 4;
|
42
|
+
case 'excerpt':
|
43
|
+
return 3;
|
44
|
+
default:
|
45
|
+
return 0;
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
window.addEventListener('load', function() {
|
50
|
+
var searchParam = new URLSearchParams(window.location.search).get("q")
|
51
|
+
if (searchParam != null) {
|
52
|
+
document.getElementById('search-input').value = searchParam
|
53
|
+
sjs.search(searchParam)
|
54
|
+
}
|
55
|
+
document.getElementById('search-input').placeholder = "Type your search here..."
|
56
|
+
}, false);
|
57
|
+
</script>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
{% for tag in post.tags %}
|
2
|
+
<a class="tag" href="/search/?q={{ tag }}">{{ tag }}</a>{% unless forloop.last %}, {% endunless %}
|
3
|
+
{% endfor %}
|
4
|
+
{% for tag in page.tags %}
|
5
|
+
<a class="tag" href="/search/?q={{ tag }}">{{ tag }}</a>{% unless forloop.last %}, {% endunless %}
|
6
|
+
{% endfor %}
|