1
1
const { DateTime } = require ( "luxon" ) ;
2
2
const readingTime = require ( 'eleventy-plugin-reading-time' )
3
3
const embedEverything = require ( "eleventy-plugin-embed-everything" )
4
+ const pluginRss = require ( "@11ty/eleventy-plugin-rss" ) ;
5
+ const pluginSyntaxHighlight = require ( "@11ty/eleventy-plugin-syntaxhighlight" ) ;
6
+ const markdownIt = require ( "markdown-it" ) ;
7
+ const markdownItAnchor = require ( "markdown-it-anchor" ) ;
8
+ const markdownItFootnote = require ( "markdown-it-footnote" ) ;
9
+ const markdownItContainer = require ( "markdown-it-container" )
10
+ const markdownItResponsive = require ( '@gerhobbelt/markdown-it-responsive' )
11
+
12
+ const transforms = require ( './utils/transforms.js' )
13
+ const filters = require ( './utils/filters.js' )
4
14
5
15
const now = new Date ( )
16
+ const envLong = process . env . NODE_ENV
6
17
7
18
module . exports = ( config ) => {
19
+ config . addPlugin ( pluginRss ) ;
20
+ config . addPlugin ( pluginSyntaxHighlight ) ;
8
21
config . addPlugin ( readingTime )
9
22
config . addPlugin ( embedEverything )
10
23
24
+ // Transforms
25
+ Object . keys ( transforms ) . forEach ( ( transformName ) => {
26
+ config . addTransform ( transformName , transforms [ transformName ] ) ;
27
+ } ) ;
28
+
29
+ // Filters
30
+ Object . keys ( filters ) . forEach ( ( filterName ) => {
31
+ config . addFilter ( filterName , filters [ filterName ] ) ;
32
+ } ) ;
33
+
34
+ const isDraftOrIndex = ( post ) => {
35
+ if ( post . data . draft ) return false
36
+ if ( post . inputPath . includes ( '/draft' ) ) return true
37
+ if ( post . inputPath . includes ( 'draft.md' ) ) return true
38
+ if ( post . inputPath . includes ( 'index.md' ) ) return true
39
+ return false
40
+ }
41
+
11
42
// Custom collections
12
43
const livePosts = post => {
13
- if ( post . data . draft ) return false
14
- if ( post . inputPath . includes ( 'draft' ) ) return false
44
+ if ( isDraftOrIndex ( post ) ) return false
15
45
if ( post . date <= now ) return true
16
46
return false
17
47
}
18
48
49
+ const liveElements = post => {
50
+ if ( isDraftOrIndex ( post ) ) return false
51
+ return true
52
+ }
53
+
54
+ config . addPassthroughCopy ( "assets/favicon" ) ;
55
+ config . addPassthroughCopy ( { 'assets/chrisspiegl.asc' : 'chrisspiegl.asc' } ) ;
56
+
19
57
config . addCollection ( 'posts' , collection => {
20
- return collection . getFilteredByGlob ( './posts/* .md' ) . filter ( livePosts ) . reverse ( )
58
+ return collection . getFilteredByGlob ( './post/**/* .md' ) . filter ( _ => livePosts ( _ ) ) . reverse ( )
21
59
} )
60
+
22
61
config . addCollection ( 'drafts' , collection => {
23
- return collection . getFilteredByGlob ( './posts/*.md' ) . filter ( _ => ! livePosts ( _ ) ) . reverse ( ) ;
62
+ return collection . getFilteredByGlob ( './post/**/*.md' ) . filter ( _ => ! livePosts ( _ ) ) . reverse ( ) ;
63
+ } )
64
+
65
+ config . addCollection ( 'podcasts' , collection => {
66
+ return collection . getFilteredByGlob ( './podcast/**/*.md' ) . filter ( _ => livePosts ( _ ) ) . reverse ( )
67
+ } )
68
+
69
+ config . addCollection ( 'books' , ( collection ) => {
70
+ return collection . getFilteredByGlob ( './book/**/*.md' ) . filter ( _ => liveElements ( _ ) ) . reverse ( )
71
+ } )
72
+
73
+ config . addCollection ( 'movies' , ( collection ) => {
74
+ return collection . getFilteredByGlob ( './movie/**/*.md' ) . filter ( _ => liveElements ( _ ) ) . reverse ( )
75
+ } )
76
+
77
+ config . addCollection ( 'gear' , ( collection ) => {
78
+ return collection . getFilteredByGlob ( './gear/**/*.md' ) . filter ( _ => liveElements ( _ ) ) . reverse ( )
24
79
} )
25
80
26
- }
81
+ config . addCollection ( "tagList" , collection => {
82
+ let uniqueTags = new Set ( )
83
+
84
+ collection . getAllSorted ( ) . forEach ( function ( item ) {
85
+ // TODO: Currently this taglist thing shows all posts no matter that tag.
86
+ if ( ! ( 'tags' in item . data ) ) return
87
+
88
+ let tags = ( typeof item . data . tags === 'string' )
89
+ ? [ item . data . tags ]
90
+ : item . data . tags
91
+
92
+ for ( const tag of tags )
93
+ tag . startsWith ( '_' ) || uniqueTags . add ( tag )
94
+ } ) ;
95
+
96
+ return [ ...uniqueTags ] ;
97
+ } )
98
+
99
+
100
+ let md = markdownIt ( {
101
+ html : true ,
102
+ breaks : true ,
103
+ linkify : true ,
104
+ typographer : true ,
105
+ } )
106
+
107
+ // The ever-popular markdown filter.
108
+ config . addFilter ( "markdown" , ( content ) => md . render ( content ) )
109
+
110
+ md . use ( markdownItAnchor , {
111
+ permalink : true ,
112
+ permalinkClass : 'direct-link' ,
113
+ permalinkSymbol : '' ,
114
+ } )
115
+ . use ( markdownItFootnote )
116
+ . use ( markdownItContainer , 'image-hero' , { marker : '!' } )
117
+ . use ( markdownItContainer , 'signature' , { marker : '!' } )
118
+ . use ( markdownItContainer , 'image-sbs' , { marker : '!' } )
119
+ . use ( markdownItContainer , 'text-center' , { marker : '!' } )
120
+ . use ( markdownItContainer , 'side-by-side' , { marker : '!' } )
121
+ . use ( markdownItContainer , 'header-image-three' , { marker : '!' } )
122
+ . use ( markdownItContainer , 'quote-hero' , { marker : '!' } )
123
+ . use ( markdownItContainer , 'button' , { marker : '!' } )
124
+ . use ( markdownItContainer , 'container' , {
125
+ marker : '!' ,
126
+ validate : function ( params ) {
127
+ return true
128
+ } ,
129
+ render : function ( tokens , idx ) {
130
+ var m = tokens [ idx ] . info . trim ( ) // .match(/^well\s+(.*)$/);
131
+ if ( tokens [ idx ] . nesting === 1 ) {
132
+ // opening tag
133
+ let summary = m === '' ? '' : '<summary>' + md . renderInline ( m ) + '</summary>\n'
134
+ return '<details>' + summary + '<aside>'
135
+ } else {
136
+ // closing tag
137
+ return '</aside>\n</details>\n'
138
+ }
139
+ } ,
140
+ } )
141
+
142
+ // Responsive Images inside Markdown
143
+
144
+ const imageResizer = ( width , height , origin ) => {
145
+ baseUrl = ! origin . startsWith ( 'https://' ) && ! origin . startsWith ( 'http://' ) ? `https://chrisspiegl.com${ origin } ` : origin
146
+ if ( process . env . ELEVENTY_ENV == 'production' ) return `https://wrender.spiegl.co/resize/${ width } /${ height } /${ baseUrl } `
147
+ else return `${ origin } `
148
+ }
149
+ md . use ( markdownItResponsive , {
150
+ responsive : {
151
+ srcset : {
152
+ "*" : [
153
+ {
154
+ width : 320 ,
155
+ rename : { suffix : "-320w" } ,
156
+ } ,
157
+ {
158
+ width : 640 ,
159
+ rename : { suffix : "-640w" } ,
160
+ } ,
161
+ {
162
+ width : 1280 ,
163
+ rename : { suffix : "-1280w" } ,
164
+ } ,
165
+ {
166
+ width : 1920 ,
167
+ rename : { suffix : "-1920w" } ,
168
+ } ,
169
+ // {
170
+ // width: 3840,
171
+ // rename: { suffix: "-3840w" },
172
+ // },
173
+ ] ,
174
+ } ,
175
+ sizes : {
176
+ // "*": "(max-width: 320px), (max-width: 640px), (max-width: 1280px), 1920px",
177
+ } ,
178
+ } ,
179
+ } ) ;
180
+
181
+ md . renderer . rules . footnote_caption = ( tokens , idx ) => {
182
+ let n = Number ( tokens [ idx ] . meta . id + 1 ) . toString ( ) ;
183
+
184
+ if ( tokens [ idx ] . meta . subId > 0 ) {
185
+ n += ":" + tokens [ idx ] . meta . subId ;
186
+ }
187
+
188
+ return n ;
189
+ } ;
190
+
191
+ config . setLibrary ( "md" , md ) ;
192
+
193
+ return {
194
+ dir : {
195
+ output : `_site_${ envLong } ` ,
196
+ } ,
197
+ // dir: {
198
+ // output: "dist",
199
+ // input: "src",
200
+ // includes: "_includes", // These are inside the `input` directory
201
+ // data: "_data"
202
+ // },
203
+ // templateFormats: [
204
+ // "md",
205
+ // "njk",
206
+ // "html"
207
+ // ],
208
+ // dataTemplateEngine: "njk",
209
+ // htmlTemplateEngine: "njk",
210
+ markdownTemplateEngine : "njk" ,
211
+ passthroughFileCopy : true
212
+ }
213
+ }
0 commit comments