minimaJake 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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>