minimaJake 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +41 -0
  4. data/_includes/custom/anchor_headings.html +164 -0
  5. data/_includes/custom/contents.html +180 -0
  6. data/_includes/custom/donatebutton.html +1 -0
  7. data/_includes/custom/donatefloating.html +9 -0
  8. data/_includes/custom/paginator.html +145 -0
  9. data/_includes/custom/read_time.html +5 -0
  10. data/_includes/custom/search.html +57 -0
  11. data/_includes/custom/tags.html +6 -0
  12. data/_includes/footer.html +26 -0
  13. data/_includes/google-analytics.html +9 -0
  14. data/_includes/head.html +14 -0
  15. data/_includes/header.html +39 -0
  16. data/_includes/social/icons/code.svg +1 -0
  17. data/_includes/social/icons/devto.svg +1 -0
  18. data/_includes/social/icons/dribbble.svg +1 -0
  19. data/_includes/social/icons/email.svg +1 -0
  20. data/_includes/social/icons/facebook.svg +1 -0
  21. data/_includes/social/icons/flickr.svg +1 -0
  22. data/_includes/social/icons/github.svg +1 -0
  23. data/_includes/social/icons/gitlab.svg +1 -0
  24. data/_includes/social/icons/google_scholar.svg +1 -0
  25. data/_includes/social/icons/instagram.svg +1 -0
  26. data/_includes/social/icons/keybase.svg +4 -0
  27. data/_includes/social/icons/linkedin.svg +1 -0
  28. data/_includes/social/icons/mastodon.svg +1 -0
  29. data/_includes/social/icons/microdotblog.svg +1 -0
  30. data/_includes/social/icons/pinterest.svg +1 -0
  31. data/_includes/social/icons/rss.svg +1 -0
  32. data/_includes/social/icons/stackoverflow.svg +1 -0
  33. data/_includes/social/icons/substack.svg +1 -0
  34. data/_includes/social/icons/telegram.svg +1 -0
  35. data/_includes/social/icons/twitter.svg +1 -0
  36. data/_includes/social/icons/youtube.svg +1 -0
  37. data/_includes/social/meta-item.html +8 -0
  38. data/_includes/social/meta.html +7 -0
  39. data/_includes/social/social-item.html +7 -0
  40. data/_includes/social/social.html +7 -0
  41. data/_includes/social/svg_symbol.html +3 -0
  42. data/_layouts/default.html +20 -0
  43. data/_layouts/home.html +59 -0
  44. data/_layouts/page.html +16 -0
  45. data/_layouts/post.html +63 -0
  46. data/_sass/minima/_base.scss +281 -0
  47. data/_sass/minima/_layout.scss +341 -0
  48. data/_sass/minima/custom-styles.scss +2 -0
  49. data/_sass/minima/custom-variables.scss +1 -0
  50. data/_sass/minima/initialize.scss +50 -0
  51. data/_sass/minima/skins/auto.scss +361 -0
  52. data/_sass/minima/skins/classic.scss +5 -0
  53. data/_sass/minima/skins/dark.scss +5 -0
  54. data/_sass/minima/skins/solarized-dark.scss +5 -0
  55. data/_sass/minima/skins/solarized-light.scss +4 -0
  56. data/_sass/minima/skins/solarized.scss +201 -0
  57. data/assets/css/style.scss +194 -0
  58. data/assets/js/posts.json +15 -0
  59. data/assets/js/search.js +438 -0
  60. data/assets/minima-social-icons.liquid +15 -0
  61. metadata +165 -0
@@ -0,0 +1,194 @@
1
+ ---
2
+ # Only the main Sass file needs front matter (the dashes are enough)
3
+ ---
4
+
5
+ @import
6
+ "minima/skins/{{ site.minima.skin | default: 'classic' }}",
7
+ "minima/initialize";
8
+
9
+ /* Misc tidying of overall layout */
10
+ .content {
11
+ padding: 15px;
12
+ }
13
+
14
+ .site-header {
15
+ border-top: 0px;
16
+ }
17
+
18
+ .card {
19
+ border: 1px solid {{ site.accent_colour }};
20
+ border-radius: .25rem;
21
+ }
22
+
23
+ .bg-img {
24
+ background-size: cover;
25
+ min-height: 180px;
26
+ background-position: center;
27
+ background-color: #fff;
28
+ }
29
+
30
+ .post-title {
31
+ line-height: 1.3;
32
+ }
33
+
34
+ .post-header .bg-img {
35
+ background-size: cover;
36
+ min-height: 180px;
37
+ background-position: center;
38
+ background-color: #fff;
39
+ border: 1px solid {{ site.accent_colour }};
40
+ border-radius: .25rem;
41
+ }
42
+
43
+ .centred-content {
44
+ margin: auto;
45
+ text-align: center;
46
+ }
47
+
48
+ /* Makes the meta info pretty */
49
+ .contact-list li+li {
50
+ padding-top: 5px;
51
+ }
52
+
53
+ .contact-list .svg-icon {
54
+ padding-right: 5px;
55
+ }
56
+
57
+ .contact-list a:hover {
58
+ text-decoration: none;
59
+ }
60
+
61
+ .contact-list a:hover .username {
62
+ text-decoration: underline;
63
+ }
64
+
65
+ .svg-icon {
66
+ fill: #828282;
67
+ }
68
+
69
+ a:hover .svg-icon {
70
+ fill: {{ site.accent_colour }};
71
+ }
72
+
73
+ /* Fixes the in-post indent applying to homepage */
74
+ .homepage-title {
75
+ margin-left: 0px;
76
+ padding-left: 0px;
77
+ }
78
+
79
+ /* Fixes weird table word break behaviour */
80
+ table {
81
+ table-layout: fixed;
82
+ word-break: break-word;
83
+ }
84
+
85
+ /* Fixes "tag" styling */
86
+ .tag,
87
+ .tag:visited {
88
+ color: #828282;
89
+ }
90
+
91
+ /* Fixes icon / username alignment in footer */
92
+ .username,
93
+ .svg-icon {
94
+ vertical-align: middle;
95
+ }
96
+
97
+ /* Styles the pagination & link to other blog */
98
+ .centred-homepage-content {
99
+ width: 100%;
100
+ text-align: center;
101
+ }
102
+
103
+ .highlight {
104
+ background: {{ site.accent_colour }};
105
+ }
106
+
107
+ /* Adds extra padding to top right links */
108
+ .page-link {
109
+ padding: 5px;
110
+ }
111
+
112
+ /* Adds GitHub style links to headers on mouseover */
113
+ .post-content h2 {
114
+ text-indent: -10px;
115
+ overflow-wrap: break-word;
116
+ }
117
+
118
+ .post-content h3 {
119
+ text-indent: -8px;
120
+ overflow-wrap: break-word;
121
+ }
122
+
123
+ .post-content h4 {
124
+ text-indent: -6px;
125
+ overflow-wrap: break-word;
126
+ }
127
+
128
+ .post-content h5 {
129
+ text-indent: -4px;
130
+ overflow-wrap: break-word;
131
+ }
132
+
133
+ .post-content h6 {
134
+ text-indent: -2px;
135
+ overflow-wrap: break-word;
136
+ }
137
+
138
+ h1 .octicon, h2 .octicon, h3 .octicon, h4 .octicon, h5 .octicon, h6 .octicon {
139
+ visibility: hidden;
140
+ }
141
+
142
+ h1:hover .octicon, h2:hover .octicon, h3:hover .octicon, h4:hover .octicon, h5:hover .octicon, h6:hover .octicon {
143
+ visibility: visible;
144
+ }
145
+
146
+ .octicon {
147
+ fill: currentColor;
148
+ padding: 0;
149
+ margin-left: -16px;
150
+ vertical-align: middle;
151
+ }
152
+
153
+ /* Table of contents */
154
+ .toc {
155
+ float: right;
156
+ border: 1px solid {{ site.accent_colour }};
157
+ border-radius: 0.25rem;
158
+ padding-top: 15px;
159
+ padding-right: 15px;
160
+ margin-left: 15px;
161
+ }
162
+
163
+ .toc b {
164
+ margin-left: 20px;
165
+ }
166
+
167
+ .toc ul {
168
+ list-style: none;
169
+ margin-left: 10px;
170
+ }
171
+
172
+ .toc li {
173
+ margin-left: 10px;
174
+ }
175
+
176
+ /* Search page */
177
+ #search-input {
178
+ font-size: 30px;
179
+ display: block;
180
+ width: 400px
181
+ }
182
+
183
+ /* Site picker */
184
+ .site-picker {
185
+ line-height: 26px;
186
+ border-bottom: 5px solid {{ site.accent_colour }};
187
+ text-align: center;
188
+ }
189
+
190
+ .site-tile {
191
+ padding: 2px 10px 3px 10px;
192
+ color: #ffffff !important;
193
+ white-space: nowrap;
194
+ }
@@ -0,0 +1,15 @@
1
+ ---
2
+ layout: none
3
+ ---
4
+ [
5
+ {% for post in site.posts %}
6
+ {
7
+ "tags" : "{{ post.tags | join: ', ' }}",
8
+ "title" : {{ post.title | jsonify | strip_html }},
9
+ "excerpt" : {{ post.excerpt | jsonify | strip_html }},
10
+ "url" : "{{ post.url }}",
11
+ "date" : "{{ post.date | date: "%b %-d, %Y" }}",
12
+ "content" : {{ post.content | jsonify | strip_html }}
13
+ } {% unless forloop.last %},{% endunless %}
14
+ {% endfor %}
15
+ ]
@@ -0,0 +1,438 @@
1
+ /*!
2
+ * Simple-Jekyll-Search
3
+ * Copyright 2015-2020, Christian Fei
4
+ * Licensed under the MIT License.
5
+ */
6
+
7
+ (function(){
8
+ 'use strict'
9
+
10
+ var _$Templater_7 = {
11
+ compile: compile,
12
+ setOptions: setOptions
13
+ }
14
+
15
+ const options = {}
16
+ options.pattern = /\{(.*?)\}/g
17
+ options.template = ''
18
+ options.middleware = function () {}
19
+
20
+ function setOptions (_options) {
21
+ options.pattern = _options.pattern || options.pattern
22
+ options.template = _options.template || options.template
23
+ if (typeof _options.middleware === 'function') {
24
+ options.middleware = _options.middleware
25
+ }
26
+ }
27
+
28
+ function compile (data) {
29
+ return options.template.replace(options.pattern, function (match, prop) {
30
+ const value = options.middleware(prop, data[prop], options.template)
31
+ if (typeof value !== 'undefined') {
32
+ return value
33
+ }
34
+ return data[prop] || match
35
+ })
36
+ }
37
+
38
+ 'use strict';
39
+
40
+ function fuzzysearch (needle, haystack) {
41
+ var tlen = haystack.length;
42
+ var qlen = needle.length;
43
+ if (qlen > tlen) {
44
+ return false;
45
+ }
46
+ if (qlen === tlen) {
47
+ return needle === haystack;
48
+ }
49
+ outer: for (var i = 0, j = 0; i < qlen; i++) {
50
+ var nch = needle.charCodeAt(i);
51
+ while (j < tlen) {
52
+ if (haystack.charCodeAt(j++) === nch) {
53
+ continue outer;
54
+ }
55
+ }
56
+ return false;
57
+ }
58
+ return true;
59
+ }
60
+
61
+ var _$fuzzysearch_1 = fuzzysearch;
62
+
63
+ 'use strict'
64
+
65
+ /* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
66
+
67
+ var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
68
+
69
+ function FuzzySearchStrategy () {
70
+ this.matches = function (string, crit) {
71
+ return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
72
+ }
73
+ }
74
+
75
+ 'use strict'
76
+
77
+ var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
78
+
79
+ function LiteralSearchStrategy () {
80
+ this.matches = function (str, crit) {
81
+ if (!str) return false
82
+
83
+ str = str.trim().toLowerCase()
84
+ crit = crit.trim().toLowerCase()
85
+
86
+ return crit.split(' ').filter(function (word) {
87
+ return str.indexOf(word) >= 0
88
+ }).length === crit.split(' ').length
89
+ }
90
+ }
91
+
92
+ 'use strict'
93
+
94
+ var _$Repository_4 = {
95
+ put: put,
96
+ clear: clear,
97
+ search: search,
98
+ setOptions: __setOptions_4
99
+ }
100
+
101
+ /* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
102
+ /* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
103
+
104
+ function NoSort () {
105
+ return 0
106
+ }
107
+
108
+ const data = []
109
+ let opt = {}
110
+
111
+ opt.fuzzy = false
112
+ opt.limit = 10
113
+ opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
114
+ opt.sort = NoSort
115
+ opt.exclude = []
116
+
117
+ function put (data) {
118
+ if (isObject(data)) {
119
+ return addObject(data)
120
+ }
121
+ if (isArray(data)) {
122
+ return addArray(data)
123
+ }
124
+ return undefined
125
+ }
126
+ function clear () {
127
+ data.length = 0
128
+ return data
129
+ }
130
+
131
+ function isObject (obj) {
132
+ return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
133
+ }
134
+
135
+ function isArray (obj) {
136
+ return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
137
+ }
138
+
139
+ function addObject (_data) {
140
+ data.push(_data)
141
+ return data
142
+ }
143
+
144
+ function addArray (_data) {
145
+ const added = []
146
+ clear()
147
+ for (let i = 0, len = _data.length; i < len; i++) {
148
+ if (isObject(_data[i])) {
149
+ added.push(addObject(_data[i]))
150
+ }
151
+ }
152
+ return added
153
+ }
154
+
155
+ function search (crit) {
156
+ if (!crit) {
157
+ return []
158
+ }
159
+ return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
160
+ }
161
+
162
+ function __setOptions_4 (_opt) {
163
+ opt = _opt || {}
164
+
165
+ opt.fuzzy = _opt.fuzzy || false
166
+ opt.limit = _opt.limit || 10
167
+ opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
168
+ opt.sort = _opt.sort || NoSort
169
+ opt.exclude = _opt.exclude || []
170
+ }
171
+
172
+ function findMatches (data, crit, strategy, opt) {
173
+ const matches = []
174
+ for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
175
+ const match = findMatchesInObject(data[i], crit, strategy, opt)
176
+ if (match) {
177
+ matches.push(match)
178
+ }
179
+ }
180
+ return matches
181
+ }
182
+
183
+ function findMatchesInObject (obj, crit, strategy, opt) {
184
+ for (const key in obj) {
185
+ if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
186
+ obj.matchedField = key
187
+ return obj
188
+ }
189
+ }
190
+ }
191
+
192
+ function isExcluded (term, excludedTerms) {
193
+ for (let i = 0, len = excludedTerms.length; i < len; i++) {
194
+ const excludedTerm = excludedTerms[i]
195
+ if (new RegExp(excludedTerm).test(term)) {
196
+ return true
197
+ }
198
+ }
199
+ return false
200
+ }
201
+
202
+ /* globals ActiveXObject:false */
203
+
204
+ 'use strict'
205
+
206
+ var _$JSONLoader_2 = {
207
+ load: load
208
+ }
209
+
210
+ function load (location, callback) {
211
+ const xhr = getXHR()
212
+ xhr.open('GET', location, true)
213
+ xhr.onreadystatechange = createStateChangeListener(xhr, callback)
214
+ xhr.send()
215
+ }
216
+
217
+ function createStateChangeListener (xhr, callback) {
218
+ return function () {
219
+ if (xhr.readyState === 4 && xhr.status === 200) {
220
+ try {
221
+ callback(null, JSON.parse(xhr.responseText))
222
+ } catch (err) {
223
+ callback(err, null)
224
+ }
225
+ }
226
+ }
227
+ }
228
+
229
+ function getXHR () {
230
+ return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
231
+ }
232
+
233
+ 'use strict'
234
+
235
+ var _$OptionsValidator_3 = function OptionsValidator (params) {
236
+ if (!validateParams(params)) {
237
+ throw new Error('-- OptionsValidator: required options missing')
238
+ }
239
+
240
+ if (!(this instanceof OptionsValidator)) {
241
+ return new OptionsValidator(params)
242
+ }
243
+
244
+ const requiredOptions = params.required
245
+
246
+ this.getRequiredOptions = function () {
247
+ return requiredOptions
248
+ }
249
+
250
+ this.validate = function (parameters) {
251
+ const errors = []
252
+ requiredOptions.forEach(function (requiredOptionName) {
253
+ if (typeof parameters[requiredOptionName] === 'undefined') {
254
+ errors.push(requiredOptionName)
255
+ }
256
+ })
257
+ return errors
258
+ }
259
+
260
+ function validateParams (params) {
261
+ if (!params) {
262
+ return false
263
+ }
264
+ return typeof params.required !== 'undefined' && params.required instanceof Array
265
+ }
266
+ }
267
+
268
+ 'use strict'
269
+
270
+ var _$utils_9 = {
271
+ merge: merge,
272
+ isJSON: isJSON
273
+ }
274
+
275
+ function merge (defaultParams, mergeParams) {
276
+ const mergedOptions = {}
277
+ for (const option in defaultParams) {
278
+ mergedOptions[option] = defaultParams[option]
279
+ if (typeof mergeParams[option] !== 'undefined') {
280
+ mergedOptions[option] = mergeParams[option]
281
+ }
282
+ }
283
+ return mergedOptions
284
+ }
285
+
286
+ function isJSON (json) {
287
+ try {
288
+ if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
289
+ return true
290
+ }
291
+ return false
292
+ } catch (err) {
293
+ return false
294
+ }
295
+ }
296
+
297
+ var _$src_8 = {};
298
+ (function (window) {
299
+ 'use strict'
300
+
301
+ let options = {
302
+ searchInput: null,
303
+ resultsContainer: null,
304
+ json: [],
305
+ success: Function.prototype,
306
+ searchFinished: Function.prototype,
307
+ searchResultTemplate: '<li><a href="{url}" title="{desc}">{title}</a></li>',
308
+ templateMiddleware: Function.prototype,
309
+ sortMiddleware: function () {
310
+ return 0
311
+ },
312
+ noResultsText: 'No results found :(',
313
+ resultsText: '{#} result(s) found',
314
+ limit: 10,
315
+ fuzzy: false,
316
+ debounceTime: null,
317
+ exclude: []
318
+ }
319
+
320
+ let debounceTimerHandle
321
+ const debounce = function (func, delayMillis) {
322
+ if (delayMillis) {
323
+ clearTimeout(debounceTimerHandle)
324
+ debounceTimerHandle = setTimeout(func, delayMillis)
325
+ } else {
326
+ func.call()
327
+ }
328
+ }
329
+
330
+ const requiredOptions = ['searchInput', 'resultsContainer', 'json']
331
+
332
+ /* removed: const _$Templater_7 = require('./Templater') */;
333
+ /* removed: const _$Repository_4 = require('./Repository') */;
334
+ /* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
335
+ const optionsValidator = _$OptionsValidator_3({
336
+ required: requiredOptions
337
+ })
338
+ /* removed: const _$utils_9 = require('./utils') */;
339
+
340
+ window.SimpleJekyllSearch = function (_options) {
341
+ const errors = optionsValidator.validate(_options)
342
+ if (errors.length > 0) {
343
+ throwError('You must specify the following required options: ' + requiredOptions)
344
+ }
345
+
346
+ options = _$utils_9.merge(options, _options)
347
+
348
+ _$Templater_7.setOptions({
349
+ template: options.searchResultTemplate,
350
+ middleware: options.templateMiddleware
351
+ })
352
+
353
+ _$Repository_4.setOptions({
354
+ fuzzy: options.fuzzy,
355
+ limit: options.limit,
356
+ sort: options.sortMiddleware,
357
+ exclude: options.exclude
358
+ })
359
+
360
+ if (_$utils_9.isJSON(options.json)) {
361
+ initWithJSON(options.json)
362
+ } else {
363
+ initWithURL(options.json)
364
+ }
365
+
366
+ const rv = {
367
+ search: search
368
+ }
369
+
370
+ typeof options.success === 'function' && options.success.call(rv)
371
+ return rv
372
+ }
373
+
374
+ function initWithJSON (json) {
375
+ _$Repository_4.put(json)
376
+ registerInput()
377
+ }
378
+
379
+ function initWithURL (url) {
380
+ _$JSONLoader_2.load(url, function (err, json) {
381
+ if (err) {
382
+ throwError('failed to get JSON (' + url + ')')
383
+ }
384
+ initWithJSON(json)
385
+ })
386
+ }
387
+
388
+ function emptyResultsContainer () {
389
+ options.resultsContainer.innerHTML = ''
390
+ }
391
+
392
+ function appendToResultsContainer (text) {
393
+ options.resultsContainer.innerHTML += text
394
+ }
395
+
396
+ function registerInput () {
397
+ options.searchInput.addEventListener('input', function (e) {
398
+ if (isWhitelistedKey(e.which)) {
399
+ emptyResultsContainer()
400
+ debounce(function () { search(e.target.value) }, options.debounceTime)
401
+ }
402
+ })
403
+ }
404
+
405
+ function search (query) {
406
+ if (isValidQuery(query)) {
407
+ emptyResultsContainer()
408
+ render(_$Repository_4.search(query), query)
409
+ }
410
+ }
411
+
412
+ function render (results, query) {
413
+ const len = results.length
414
+ typeof options.searchFinished === 'function' && options.searchFinished(len)
415
+ if (len === 0) {
416
+ return appendToResultsContainer(options.noResultsText)
417
+ }
418
+ appendToResultsContainer(options.resultsText.replace("{#}", len))
419
+ for (let i = 0; i < len; i++) {
420
+ results[i].query = query
421
+ appendToResultsContainer(_$Templater_7.compile(results[i]))
422
+ }
423
+ }
424
+
425
+ function isValidQuery (query) {
426
+ return query && query.length > 1
427
+ }
428
+
429
+ function isWhitelistedKey (key) {
430
+ return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
431
+ }
432
+
433
+ function throwError (message) {
434
+ throw new Error('SimpleJekyllSearch --- ' + message)
435
+ }
436
+ })(window)
437
+
438
+ }());
@@ -0,0 +1,15 @@
1
+ ---
2
+ permalink: /assets/minima-social-icons.svg
3
+ ---
4
+
5
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
6
+ {% comment %}
7
+ Iterate through {{ site.minima.social_links }} and render platform related SVG-symbol
8
+ unless the platform is "rss" because we need the "rss" symbol for the `Subscribe` link
9
+ in the footer and therefore inject the "rss" icon outside the iteration loop.
10
+ {% endcomment %}
11
+ {% for entry in site.minima.social_links %}
12
+ {%- assign symbol_id = entry.platform -%}
13
+ {%- include social/svg_symbol.html key = symbol_id -%}
14
+ {%- endfor -%}
15
+ </svg>