poops 1.0.18 → 1.0.20
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.
- package/README.md +71 -2
- package/lib/copy.js +121 -0
- package/lib/markups.js +226 -143
- package/lib/styles.js +65 -24
- package/lib/utils/helpers.js +197 -3
- package/package.json +8 -3
- package/poops.js +12 -1
- package/.eslintrc.yml +0 -10
- package/.github/dependabot.yml +0 -9
- package/.github/workflows/npm_publish.yml +0 -17
- package/.nojekyll +0 -1
- package/changelog/blog-functionality.html +0 -58
- package/changelog/feed.rss +0 -31
- package/changelog/front-matter.html +0 -61
- package/changelog/index.html +0 -74
- package/changelog/markdown-support.html +0 -56
- package/example/dist/css/styles.css +0 -7172
- package/example/dist/css/styles.css.map +0 -1
- package/example/dist/css/styles.min.css +0 -2
- package/example/dist/js/scripts.js +0 -35
- package/example/dist/js/scripts.js.map +0 -7
- package/example/dist/js/scripts.min.js +0 -2
- package/example/src/js/main.ts +0 -28
- package/example/src/js/scripts/utils.ts +0 -16
- package/example/src/markup/_data/features.yaml +0 -9
- package/example/src/markup/_data/links.json +0 -10
- package/example/src/markup/_data/poops.yaml +0 -7
- package/example/src/markup/_layouts/blog.html +0 -35
- package/example/src/markup/_layouts/default.html +0 -93
- package/example/src/markup/_partials/heading.html +0 -10
- package/example/src/markup/_partials/site-header.html +0 -17
- package/example/src/markup/changelog/blog-functionality.md +0 -9
- package/example/src/markup/changelog/feed.rss +0 -23
- package/example/src/markup/changelog/front-matter.md +0 -12
- package/example/src/markup/changelog/index.html +0 -30
- package/example/src/markup/changelog/markdown-support.md +0 -7
- package/example/src/markup/index.html +0 -33
- package/example/src/scss/_config.scss +0 -22
- package/example/src/scss/index.scss +0 -4
- package/example/src/scss/style/index.scss +0 -13
- package/example/src/scss/style/test.css +0 -3
- package/index.html +0 -166
- package/poop.png +0 -0
- package/script/build +0 -3
- package/script/publish +0 -138
- package/script/server +0 -3
- package/test.html +0 -96
- package/tsconfig.json +0 -16
- package//360/237/222/251.json +0 -55
package/lib/markups.js
CHANGED
|
@@ -5,7 +5,7 @@ const nunjucks = require('nunjucks')
|
|
|
5
5
|
const path = require('node:path')
|
|
6
6
|
const PrintStyle = require('./utils/print-style.js')
|
|
7
7
|
|
|
8
|
-
const { pathExists, pathIsDirectory, readDataFile, deleteDirectory } = helpers
|
|
8
|
+
const { pathExists, pathIsDirectory, readDataFile, deleteDirectory, mkDir, parseFrontMatter, clearFrontMatterCache } = helpers
|
|
9
9
|
const pstyle = new PrintStyle()
|
|
10
10
|
|
|
11
11
|
class RelativeLoader extends nunjucks.Loader {
|
|
@@ -13,7 +13,7 @@ class RelativeLoader extends nunjucks.Loader {
|
|
|
13
13
|
super()
|
|
14
14
|
this.templatesDir = templatesDir
|
|
15
15
|
this.includePaths = includePaths || []
|
|
16
|
-
this.includePaths.push('_*') // XXX: It is better to define templates and layouts directories in the config file? then all
|
|
16
|
+
this.includePaths.push('_*') // XXX: It is better to define templates and layouts directories in the config file? then all together include paths?
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
getSource(name) {
|
|
@@ -31,12 +31,16 @@ class RelativeLoader extends nunjucks.Loader {
|
|
|
31
31
|
return { src: '', path: fullPath, noCache: true }
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
let source =
|
|
34
|
+
let source = ''
|
|
35
35
|
let frontMatter = {}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const frontMatterResult = parseFrontMatter(fullPath)
|
|
39
|
+
frontMatter = frontMatterResult.frontMatter
|
|
40
|
+
source = frontMatterResult.content
|
|
41
|
+
} catch (err) {
|
|
42
|
+
console.log(`${pstyle.redBright + pstyle.bold}[error]${pstyle.reset}${pstyle.dim} Failed parsing front matter:${pstyle.reset} ${pstyle.italic + pstyle.underline}${fullPath}${pstyle.reset}`)
|
|
43
|
+
console.log(err)
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
if (path.extname(fullPath) === '.md') {
|
|
@@ -194,7 +198,15 @@ module.exports = class Markups {
|
|
|
194
198
|
getSingleCollectionData(collectionName) {
|
|
195
199
|
const collectionData = []
|
|
196
200
|
glob.sync(path.join(process.cwd(), this.config.markup.in, collectionName, '**/*.+(html|njk|md)'), { ignore: ['**/index.+(html|njk|md)'] }).forEach((file) => {
|
|
197
|
-
|
|
201
|
+
let frontMatter = {}
|
|
202
|
+
|
|
203
|
+
try {
|
|
204
|
+
const frontMatterResult = parseFrontMatter(file)
|
|
205
|
+
frontMatter = frontMatterResult.frontMatter
|
|
206
|
+
} catch (err) {
|
|
207
|
+
console.log(`${pstyle.redBright + pstyle.bold}[error]${pstyle.reset}${pstyle.dim} Failed parsing front matter:${pstyle.reset} ${pstyle.italic + pstyle.underline}${file}${pstyle.reset}`)
|
|
208
|
+
console.log(err)
|
|
209
|
+
}
|
|
198
210
|
|
|
199
211
|
if (frontMatter.published === false) return // Skip unpublished items
|
|
200
212
|
|
|
@@ -223,69 +235,109 @@ module.exports = class Markups {
|
|
|
223
235
|
const collectionData = {}
|
|
224
236
|
|
|
225
237
|
for (const indexFile of indexFiles) {
|
|
226
|
-
|
|
238
|
+
let frontMatter = {}
|
|
239
|
+
|
|
240
|
+
try {
|
|
241
|
+
const frontMatterResult = parseFrontMatter(indexFile)
|
|
242
|
+
frontMatter = frontMatterResult.frontMatter
|
|
243
|
+
} catch (err) {
|
|
244
|
+
console.log(`${pstyle.redBright + pstyle.bold}[error]${pstyle.reset}${pstyle.dim} Failed parsing front matter:${pstyle.reset} ${pstyle.italic + pstyle.underline}${indexFile}${pstyle.reset}`)
|
|
245
|
+
console.log(err)
|
|
246
|
+
}
|
|
247
|
+
|
|
227
248
|
if (!frontMatter.collection) continue
|
|
228
249
|
|
|
229
250
|
if (frontMatter.collection === true) {
|
|
230
251
|
frontMatter.collection = path.basename(path.dirname(indexFile))
|
|
231
252
|
}
|
|
232
253
|
|
|
233
|
-
|
|
254
|
+
const collectionName = frontMatter.collection.trim()
|
|
234
255
|
|
|
235
|
-
|
|
256
|
+
if (collectionName === '') continue
|
|
236
257
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
258
|
+
frontMatter.name = collectionName
|
|
259
|
+
const collection = this.buildCollectionObject(frontMatter)
|
|
260
|
+
if (!collection) continue
|
|
261
|
+
collectionData[collection.name] = collection
|
|
262
|
+
}
|
|
240
263
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
264
|
+
return collectionData
|
|
265
|
+
}
|
|
244
266
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
267
|
+
getCollectionDataBasedOnConfig(collectionConfig) {
|
|
268
|
+
if (!collectionConfig) return {}
|
|
248
269
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
270
|
+
const items = Array.isArray(collectionConfig)
|
|
271
|
+
? collectionConfig
|
|
272
|
+
: [collectionConfig]
|
|
252
273
|
|
|
253
|
-
|
|
254
|
-
collection.sort.by = 'date'
|
|
255
|
-
}
|
|
274
|
+
const collectionData = {}
|
|
256
275
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
276
|
+
for (let item of items) {
|
|
277
|
+
if (typeof item === 'string') item = { name: item }
|
|
278
|
+
if (!item || !item.name) continue
|
|
279
|
+
const collection = this.buildCollectionObject(item)
|
|
280
|
+
if (collection) collectionData[item.name] = collection
|
|
281
|
+
}
|
|
262
282
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
}
|
|
283
|
+
return collectionData
|
|
284
|
+
}
|
|
266
285
|
|
|
267
|
-
|
|
286
|
+
buildCollectionObject(collectionProtoObject) {
|
|
287
|
+
const collection = {
|
|
288
|
+
name: collectionProtoObject.name,
|
|
289
|
+
items: this.getSingleCollectionData(collectionProtoObject.name)
|
|
290
|
+
}
|
|
268
291
|
|
|
269
|
-
|
|
292
|
+
if (collection.items.length === 0) return null
|
|
270
293
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
return new Date(a[collection.sort.by]) - new Date(b[collection.sort.by])
|
|
275
|
-
}
|
|
294
|
+
if (collectionProtoObject.paginate && !isNaN(parseInt(collectionProtoObject.paginate))) {
|
|
295
|
+
collection.paginate = parseInt(collectionProtoObject.paginate)
|
|
296
|
+
}
|
|
276
297
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
return a[collection.sort.by] > b[collection.sort.by] ? 1 : -1
|
|
281
|
-
}
|
|
298
|
+
if (collectionProtoObject.sort) {
|
|
299
|
+
collection.sort = collectionProtoObject.sort
|
|
300
|
+
}
|
|
282
301
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
})
|
|
302
|
+
if (typeof collection.sort === 'string') {
|
|
303
|
+
collection.sort = { by: collection.sort }
|
|
286
304
|
}
|
|
287
305
|
|
|
288
|
-
|
|
306
|
+
if (!collection.sort) {
|
|
307
|
+
collection.sort = { by: 'date' }
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (!collection.sort.by) {
|
|
311
|
+
collection.sort.by = 'date'
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (collection.sort.by === 'date') {
|
|
315
|
+
collection.sort.type = 'date'
|
|
316
|
+
} else {
|
|
317
|
+
collection.sort.type = 'alphabetical'
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (!collection.sort.order) {
|
|
321
|
+
collection.sort.order = collection.sort.type === 'date' ? 'desc' : 'asc'
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
collection.items.sort((a, b) => {
|
|
325
|
+
if (collection.sort.type === 'date') {
|
|
326
|
+
if (collection.sort.order === 'asc') {
|
|
327
|
+
return new Date(a[collection.sort.by]) - new Date(b[collection.sort.by])
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
return new Date(b[collection.sort.by]) - new Date(a[collection.sort.by])
|
|
331
|
+
} else {
|
|
332
|
+
if (collection.sort.order === 'asc') {
|
|
333
|
+
return a[collection.sort.by] > b[collection.sort.by] ? 1 : -1
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return a[collection.sort.by] < b[collection.sort.by] ? 1 : -1
|
|
337
|
+
}
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
return collection
|
|
289
341
|
}
|
|
290
342
|
|
|
291
343
|
clearCollectionOutputDir(collectionName) {
|
|
@@ -293,15 +345,27 @@ module.exports = class Markups {
|
|
|
293
345
|
deleteDirectory(collectionDirectoryPath) // Remove collection directory
|
|
294
346
|
}
|
|
295
347
|
|
|
296
|
-
getRelativePathPrefix(outputDir) {
|
|
297
|
-
|
|
348
|
+
getRelativePathPrefix(outputDir, fromDir) {
|
|
349
|
+
let relativeDir = path.relative(process.cwd(), outputDir)
|
|
350
|
+
const fromRelativeDir = fromDir ? path.relative(process.cwd(), fromDir) : ''
|
|
351
|
+
|
|
352
|
+
if (fromRelativeDir && relativeDir.startsWith(fromRelativeDir)) {
|
|
353
|
+
relativeDir = relativeDir.replace(fromRelativeDir, '')
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
return this.getUpDirPrefix(relativeDir)
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
getUpDirPrefix(relativeDir) {
|
|
298
360
|
if (relativeDir.trim() === '') return ''
|
|
361
|
+
if (relativeDir.startsWith(path.sep)) relativeDir = relativeDir.slice(1)
|
|
362
|
+
if (relativeDir.endsWith(path.sep)) relativeDir = relativeDir.slice(0, -1)
|
|
299
363
|
const relativePathParts = relativeDir.split(path.sep)
|
|
300
|
-
let
|
|
364
|
+
let upDir = ''
|
|
301
365
|
for (let i = 0; i < relativePathParts.length; i++) {
|
|
302
|
-
|
|
366
|
+
upDir += `..${path.sep}`
|
|
303
367
|
}
|
|
304
|
-
return
|
|
368
|
+
return upDir
|
|
305
369
|
}
|
|
306
370
|
|
|
307
371
|
getPageUrl(outputPath) {
|
|
@@ -323,8 +387,6 @@ module.exports = class Markups {
|
|
|
323
387
|
}
|
|
324
388
|
|
|
325
389
|
compileEntry(templateName, additionalContext) {
|
|
326
|
-
const source = fs.readFileSync(templateName, 'utf-8')
|
|
327
|
-
const match = source.match(/^\s*---\s*([\s\S]*?)---\s*/) // Front matter match
|
|
328
390
|
const context = { page: {} }
|
|
329
391
|
let pageUrl
|
|
330
392
|
|
|
@@ -335,13 +397,13 @@ module.exports = class Markups {
|
|
|
335
397
|
}
|
|
336
398
|
Object.assign(context, additionalContext)
|
|
337
399
|
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
400
|
+
|
|
401
|
+
try {
|
|
402
|
+
const frontMatterResult = parseFrontMatter(templateName)
|
|
403
|
+
context.page = frontMatterResult.frontMatter
|
|
404
|
+
} catch (err) {
|
|
405
|
+
console.log(`${pstyle.redBright + pstyle.bold}[error]${pstyle.reset}${pstyle.dim} Failed parsing front matter:${pstyle.reset} ${pstyle.italic + pstyle.underline}${templateName}${pstyle.reset}`)
|
|
406
|
+
console.log(err)
|
|
345
407
|
}
|
|
346
408
|
|
|
347
409
|
if (pageUrl) context.page.url = pageUrl
|
|
@@ -358,106 +420,122 @@ module.exports = class Markups {
|
|
|
358
420
|
})
|
|
359
421
|
}
|
|
360
422
|
|
|
423
|
+
getCollectionIndexFile(collectionName) {
|
|
424
|
+
const indexFiles = glob.sync(path.join(process.cwd(), this.config.markup.in, collectionName, 'index.+(html|njk|md)'))
|
|
425
|
+
if (indexFiles.length === 0) return null
|
|
426
|
+
return indexFiles[0]
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
buildCollectionPaginationData(collectionData) {
|
|
430
|
+
if (!collectionData) return
|
|
431
|
+
|
|
432
|
+
for (const collectionName of Object.keys(collectionData)) {
|
|
433
|
+
const collection = collectionData[collectionName]
|
|
434
|
+
|
|
435
|
+
if (!collection.paginate) continue
|
|
436
|
+
|
|
437
|
+
collection.pages = []
|
|
438
|
+
let pageItems = []
|
|
439
|
+
for (const item of collection.items) {
|
|
440
|
+
if (pageItems.length === collection.paginate) {
|
|
441
|
+
collection.pages.push(pageItems)
|
|
442
|
+
pageItems = []
|
|
443
|
+
}
|
|
444
|
+
pageItems.push(item)
|
|
445
|
+
}
|
|
446
|
+
collection.pages.push(pageItems)
|
|
447
|
+
|
|
448
|
+
collection.totalPages = collection.pages.length
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
generateCollectionPaginationPages(collectionData, compilePromises) {
|
|
453
|
+
if (!collectionData) return
|
|
454
|
+
|
|
455
|
+
for (const collectionName of Object.keys(collectionData)) {
|
|
456
|
+
const collection = collectionData[collectionName]
|
|
457
|
+
const file = this.getCollectionIndexFile(collectionName)
|
|
458
|
+
|
|
459
|
+
if (!collection.totalPages || collection.totalPages === 0) {
|
|
460
|
+
collection.totalPages = 1
|
|
461
|
+
collection.pages = [collection.items]
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
for (let i = 0; i < collection.totalPages; i++) {
|
|
465
|
+
collection.pageItems = collection.pages[i]
|
|
466
|
+
collection.pageNumber = i + 1
|
|
467
|
+
collection.pageUrl = collection.pageNumber === 1 ? collection.name : `${collection.name}/${collection.pageNumber}`
|
|
468
|
+
collection.nextPage = collection.pageNumber === collection.totalPages ? null : collection.pageNumber + 1
|
|
469
|
+
collection.nextPageUrl = collection.pageNumber === collection.totalPages ? null : `${collection.name}/${collection.pageNumber + 1}`
|
|
470
|
+
collection.prevPage = collection.pageNumber === 1 ? null : collection.pageNumber - 1
|
|
471
|
+
collection.prevPageUrl = collection.pageNumber === 1 ? null : `${collection.name}/${collection.pageNumber - 1}`
|
|
472
|
+
if (collection.prevPage === 1) {
|
|
473
|
+
collection.prevPageUrl = collection.name
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
const markupOut = path.join(process.cwd(), this.config.markup.out, collection.pageUrl, 'index.html')
|
|
477
|
+
const fromPath = path.join(process.cwd(), this.config.markup.out)
|
|
478
|
+
const markupOutDir = path.dirname(markupOut)
|
|
479
|
+
|
|
480
|
+
mkDir(markupOutDir)
|
|
481
|
+
|
|
482
|
+
collectionData.relativePathPrefix = this.getRelativePathPrefix(markupOutDir, fromPath)
|
|
483
|
+
collectionData._url = this.getPageUrl(markupOut)
|
|
484
|
+
|
|
485
|
+
if (!file) {
|
|
486
|
+
continue
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
const compilePromise = this.compileEntry(file, collectionData).then((result) => {
|
|
490
|
+
fs.writeFileSync(markupOut, result)
|
|
491
|
+
})
|
|
492
|
+
compilePromises.push(compilePromise)
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
361
497
|
compile() {
|
|
362
|
-
// TODO: should support multiple markup paths, for loop here!
|
|
363
498
|
if (!this.config.markup || !this.config.markup.in) return
|
|
364
499
|
|
|
365
500
|
const markupIn = path.join(process.cwd(), this.config.markup.in)
|
|
501
|
+
const compilePromises = []
|
|
366
502
|
|
|
367
503
|
if (!pathExists(markupIn)) {
|
|
368
504
|
console.log(`${pstyle.redBright + pstyle.bold}[error]${pstyle.reset} ${pstyle.dim}Markup path does not exist:${pstyle.reset} ${pstyle.italic + pstyle.underline}${markupIn}${pstyle.reset}`)
|
|
369
505
|
return
|
|
370
506
|
}
|
|
371
507
|
|
|
508
|
+
const collectionData = {
|
|
509
|
+
...this.collectionAutoDiscovery(),
|
|
510
|
+
...this.getCollectionDataBasedOnConfig(this.config.markup.options.collections)
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// Create collection pages
|
|
514
|
+
this.buildCollectionPaginationData(collectionData)
|
|
515
|
+
this.generateCollectionPaginationPages(collectionData, compilePromises)
|
|
516
|
+
|
|
372
517
|
if (pathIsDirectory(markupIn)) {
|
|
373
518
|
const markupFiles = [...glob.sync(path.join(markupIn, this.generateMarkupGlobPattern(this.includePaths))), ...glob.sync(path.join(markupIn, '*.+(html|xml|rss|atom|json|njk|md)'))]
|
|
374
|
-
|
|
375
|
-
const compilePromises = []
|
|
519
|
+
|
|
376
520
|
markupFiles.forEach((file) => {
|
|
377
521
|
const relativePath = path.relative(markupIn, file)
|
|
378
522
|
const relativePathParts = relativePath.split(path.sep)
|
|
379
523
|
|
|
380
|
-
//
|
|
524
|
+
// Collection pages already generated, skip them
|
|
381
525
|
if (relativePathParts.length > 1 &&
|
|
382
526
|
collectionData[relativePathParts[0]] &&
|
|
383
|
-
(
|
|
527
|
+
/^index\.(html|njk|md)$/.test(relativePathParts[1]) &&
|
|
384
528
|
collectionData[relativePathParts[0]].items.length > 0) {
|
|
385
|
-
let frontMatter = {}
|
|
386
|
-
const source = fs.readFileSync(file, 'utf-8')
|
|
387
|
-
const match = source.match(/^\s*---\s*([\s\S]*?)---\s*/) // Front matter match
|
|
388
|
-
if (match) {
|
|
389
|
-
try {
|
|
390
|
-
frontMatter = require('yaml').parse(match[1]) // Pass front matter to the template
|
|
391
|
-
} catch (err) {
|
|
392
|
-
console.log(`${pstyle.redBright + pstyle.bold}[error]${pstyle.reset}${pstyle.dim} Failed parsing front matter:${pstyle.reset} ${pstyle.italic + pstyle.underline}${file}${pstyle.reset}`)
|
|
393
|
-
console.log(err)
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
if (frontMatter.paginate && !isNaN(parseInt(frontMatter.paginate))) {
|
|
398
|
-
frontMatter.paginate = parseInt(frontMatter.paginate)
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
// TODO: sorting should be done via frontMatter not the config file. Collection autodiscovery from frontMatter as well
|
|
402
|
-
|
|
403
|
-
const collectionName = relativePathParts[0]
|
|
404
|
-
|
|
405
|
-
if (frontMatter.paginate) {
|
|
406
|
-
const collection = collectionData[collectionName]
|
|
407
|
-
collection.paginate = frontMatter.paginate
|
|
408
|
-
collection.pages = []
|
|
409
|
-
let pageItems = []
|
|
410
|
-
for (const item of collection.items) {
|
|
411
|
-
if (pageItems.length === collection.paginate) {
|
|
412
|
-
collection.pages.push(pageItems)
|
|
413
|
-
pageItems = []
|
|
414
|
-
}
|
|
415
|
-
pageItems.push(item)
|
|
416
|
-
}
|
|
417
|
-
collection.pages.push(pageItems)
|
|
418
|
-
|
|
419
|
-
collection.totalPages = collection.pages.length
|
|
420
|
-
|
|
421
|
-
for (let i = 0; i < collection.totalPages; i++) {
|
|
422
|
-
collection.pageItems = collection.pages[i]
|
|
423
|
-
collection.pageNumber = i + 1
|
|
424
|
-
collection.pageUrl = collection.pageNumber === 1 ? collectionName : `${collectionName}/${collection.pageNumber}`
|
|
425
|
-
collection.nextPage = collection.pageNumber === collection.totalPages ? null : collection.pageNumber + 1
|
|
426
|
-
collection.nextPageUrl = collection.pageNumber === collection.totalPages ? null : `${collectionName}/${collection.pageNumber + 1}`
|
|
427
|
-
collection.prevPage = collection.pageNumber === 1 ? null : collection.pageNumber - 1
|
|
428
|
-
collection.prevPageUrl = collection.pageNumber === 1 ? null : `${collectionName}/${collection.pageNumber - 1}`
|
|
429
|
-
if (collection.prevPage === 1) {
|
|
430
|
-
collection.prevPageUrl = collectionName
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
const markupOut = path.join(process.cwd(), this.config.markup.out, collection.pageUrl, 'index.html')
|
|
434
|
-
const markupOutDir = path.dirname(markupOut)
|
|
435
|
-
|
|
436
|
-
if (!pathExists(markupOutDir)) {
|
|
437
|
-
fs.mkdirSync(markupOutDir, { recursive: true })
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
collectionData.relativePathPrefix = this.getRelativePathPrefix(markupOutDir)
|
|
441
|
-
collectionData._url = this.getPageUrl(markupOut)
|
|
442
|
-
|
|
443
|
-
const compilePromise = this.compileEntry(file, collectionData).then((result) => {
|
|
444
|
-
fs.writeFileSync(markupOut, result)
|
|
445
|
-
})
|
|
446
|
-
compilePromises.push(compilePromise)
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
|
|
450
529
|
return
|
|
451
530
|
}
|
|
452
531
|
|
|
453
|
-
let markupOut = path.join(process.cwd(), relativePath)
|
|
532
|
+
let markupOut = path.join(process.cwd(), this.config.markup.out, relativePath)
|
|
533
|
+
const fromPath = path.join(process.cwd(), this.config.markup.out)
|
|
454
534
|
const markupOutDir = path.dirname(markupOut)
|
|
455
535
|
|
|
456
|
-
|
|
457
|
-
fs.mkdirSync(markupOutDir, { recursive: true })
|
|
458
|
-
}
|
|
536
|
+
mkDir(markupOutDir)
|
|
459
537
|
|
|
460
|
-
collectionData.relativePathPrefix = this.getRelativePathPrefix(markupOutDir)
|
|
538
|
+
collectionData.relativePathPrefix = this.getRelativePathPrefix(markupOutDir, fromPath)
|
|
461
539
|
collectionData._url = this.getPageUrl(markupOut)
|
|
462
540
|
|
|
463
541
|
const compilePromise = this.compileEntry(file, collectionData).then((result) => {
|
|
@@ -470,27 +548,32 @@ module.exports = class Markups {
|
|
|
470
548
|
return new Promise((resolve, reject) => {
|
|
471
549
|
Promise.all(compilePromises).then(() => {
|
|
472
550
|
console.log(`${pstyle.cyanBright + pstyle.bold}[markup]${pstyle.reset} ${pstyle.dim}Compiled: ${pstyle.reset}${markupFiles.length} file${markupFiles.length > 1 ? 's' : ''} into ${pstyle.italic + pstyle.underline}${this.config.markup.out}${pstyle.reset}`)
|
|
551
|
+
clearFrontMatterCache()
|
|
473
552
|
resolve()
|
|
474
553
|
}).catch((err) => {
|
|
475
554
|
console.log(`${pstyle.cyanBright + pstyle.bold}[markup]${pstyle.reset} ${pstyle.redBright + pstyle.bold}[error]${pstyle.reset} ${pstyle.dim}Failed compiling${pstyle.reset + pstyle.bell}`)
|
|
476
555
|
console.log(err)
|
|
556
|
+
clearFrontMatterCache()
|
|
477
557
|
reject(err)
|
|
478
558
|
})
|
|
479
559
|
})
|
|
480
560
|
} else {
|
|
481
561
|
let markupOut = path.join(process.cwd(), this.config.markup.out)
|
|
482
562
|
const markupOutDir = path.dirname(markupOut)
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
563
|
+
mkDir(markupOutDir)
|
|
564
|
+
|
|
565
|
+
collectionData.relativePathPrefix = this.getRelativePathPrefix(markupOutDir)
|
|
566
|
+
collectionData._url = this.getPageUrl(markupOut)
|
|
486
567
|
|
|
487
|
-
return this.compileEntry(markupIn,
|
|
568
|
+
return this.compileEntry(markupIn, collectionData).then((result) => {
|
|
488
569
|
markupOut = this.replaceOutExtensions(markupOut)
|
|
489
570
|
fs.writeFileSync(markupOut, result)
|
|
490
571
|
console.log(`${pstyle.cyanBright + pstyle.bold}[markup]${pstyle.reset} ${pstyle.dim}Compiled:${pstyle.reset} ${pstyle.italic + pstyle.underline}${path.relative(process.cwd(), path.join(process.cwd(), this.config.markup.out, path.basename(markupIn)))}${pstyle.reset}`)
|
|
572
|
+
clearFrontMatterCache()
|
|
491
573
|
}).catch((err) => {
|
|
492
574
|
console.log(`${pstyle.cyanBright + pstyle.bold}[markup]${pstyle.reset} ${pstyle.redBright + pstyle.bold}[error]${pstyle.reset} ${pstyle.dim}Failed compiling:${pstyle.reset} ${pstyle.italic + pstyle.underline}${path.relative(process.cwd(), path.join(process.cwd(), this.config.markup.out, path.basename(markupIn)))}${pstyle.reset + pstyle.bell}`)
|
|
493
575
|
console.log(err)
|
|
576
|
+
clearFrontMatterCache()
|
|
494
577
|
})
|
|
495
578
|
}
|
|
496
579
|
}
|
package/lib/styles.js
CHANGED
|
@@ -20,47 +20,88 @@ const {
|
|
|
20
20
|
const pstyle = new PrintStyle()
|
|
21
21
|
|
|
22
22
|
function tryToFindFile(filePath, extensions) {
|
|
23
|
-
const
|
|
24
|
-
if (
|
|
25
|
-
return
|
|
23
|
+
const pathParts = path.parse(filePath)
|
|
24
|
+
if (pathParts.ext && pathParts.ext.length > 0 && extensions.includes(pathParts.ext.slice(1))) {
|
|
25
|
+
if (fs.existsSync(filePath)) return filePath
|
|
26
26
|
}
|
|
27
|
+
|
|
28
|
+
let fileExt = extensions.find(ext => fs.existsSync(`${filePath}.${ext}`))
|
|
29
|
+
if (fileExt) return `${filePath}.${fileExt}`
|
|
30
|
+
|
|
31
|
+
if (!pathParts.name.startsWith('_')) {
|
|
32
|
+
pathParts.name = `_${pathParts.name}`
|
|
33
|
+
const underscoredFilePath = path.format(pathParts)
|
|
34
|
+
fileExt = extensions.find(ext => fs.existsSync(`${underscoredFilePath}.${ext}`))
|
|
35
|
+
if (fileExt) return `${underscoredFilePath}.${fileExt}`
|
|
36
|
+
}
|
|
37
|
+
|
|
27
38
|
return null
|
|
28
39
|
}
|
|
29
40
|
|
|
41
|
+
function extractMainPathFromPackageJson(packageJsonPath) {
|
|
42
|
+
if (!pathExists(packageJsonPath, 'package.json')) return null
|
|
43
|
+
|
|
44
|
+
const pkg = require(path.join(process.cwd(), packageJsonPath, 'package.json'))
|
|
45
|
+
|
|
46
|
+
const mainPath = pkg.sass || pkg.scss || pkg.style || pkg.css || pkg.main
|
|
47
|
+
if (!mainPath) return null
|
|
48
|
+
|
|
49
|
+
return mainPath
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function getPackagePath(url) {
|
|
53
|
+
const parts = path.parse(url)
|
|
54
|
+
if (!parts.dir) return null
|
|
55
|
+
const dirChunks = parts.dir.split(path.sep)
|
|
56
|
+
if (dirChunks.length === 0) return null
|
|
57
|
+
if (dirChunks[0].startsWith('@') && dirChunks.length > 1) {
|
|
58
|
+
return path.join(dirChunks[0], dirChunks[1])
|
|
59
|
+
}
|
|
60
|
+
return dirChunks[0]
|
|
61
|
+
}
|
|
62
|
+
|
|
30
63
|
function sassPathResolver(url, resolvePath, infilePath) {
|
|
64
|
+
// check if resole path, like `node_modules` exists
|
|
31
65
|
const resolvedPath = pathToFileURL(resolvePath)
|
|
32
66
|
if (!fs.existsSync(resolvedPath.pathname)) return null
|
|
33
67
|
const importPath = path.relative(process.cwd(), path.join(resolvedPath.pathname, url))
|
|
34
68
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
69
|
+
// 1. Maybe it's a directory?
|
|
70
|
+
if (pathExists(importPath) && pathIsDirectory(importPath)) {
|
|
71
|
+
// Try to find an index file within the directory
|
|
72
|
+
const correctIndexFile = tryToFindFile(path.join(importPath, 'index'), ['sass', 'scss', 'css'])
|
|
73
|
+
if (correctIndexFile) return new URL(correctIndexFile, resolvedPath)
|
|
39
74
|
|
|
40
|
-
|
|
41
|
-
const
|
|
75
|
+
// package.json discovery
|
|
76
|
+
const style = extractMainPathFromPackageJson(importPath)
|
|
42
77
|
|
|
43
|
-
|
|
78
|
+
const stylePath = new URL(path.join(importPath, style), resolvedPath)
|
|
79
|
+
if (fs.existsSync(stylePath)) return stylePath
|
|
80
|
+
}
|
|
44
81
|
|
|
45
|
-
|
|
82
|
+
// 2. Maybe it's a file?
|
|
83
|
+
if (pathExists(importPath)) return pathToFileURL(importPath)
|
|
46
84
|
|
|
47
|
-
|
|
85
|
+
// 2.1 Try to find the correct file with different formats
|
|
86
|
+
const correctFile = tryToFindFile(importPath, ['sass', 'scss', 'css'])
|
|
87
|
+
if (correctFile) return new URL(correctFile, resolvedPath)
|
|
48
88
|
|
|
49
|
-
|
|
50
|
-
|
|
89
|
+
// 2.2 Maybe it's a file within a package?
|
|
90
|
+
const packagePath = getPackagePath(url)
|
|
91
|
+
if (packagePath) {
|
|
92
|
+
const packageFullPath = path.relative(process.cwd(), path.join(resolvedPath.pathname, packagePath))
|
|
93
|
+
const stylePath = extractMainPathFromPackageJson(packageFullPath)
|
|
51
94
|
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
|
|
95
|
+
if (stylePath) {
|
|
96
|
+
const styleDir = path.dirname(stylePath)
|
|
97
|
+
const styleFinalPath = path.join(packageFullPath, styleDir, url.replace(packagePath, ''))
|
|
55
98
|
|
|
56
|
-
|
|
57
|
-
if (
|
|
58
|
-
const stylePath = new URL(path.join(importPath, styleEntry), resolvedPath)
|
|
59
|
-
if (fs.existsSync(stylePath)) return stylePath
|
|
99
|
+
const correctPackageFile = tryToFindFile(styleFinalPath, ['sass', 'scss', 'css'])
|
|
100
|
+
if (correctPackageFile) return new URL(correctPackageFile, resolvedPath)
|
|
60
101
|
}
|
|
61
102
|
}
|
|
62
103
|
|
|
63
|
-
return
|
|
104
|
+
return null
|
|
64
105
|
}
|
|
65
106
|
|
|
66
107
|
module.exports = class Styles {
|
|
@@ -90,8 +131,8 @@ module.exports = class Styles {
|
|
|
90
131
|
// Resolve `includePaths`.
|
|
91
132
|
findFileUrl(url) {
|
|
92
133
|
for (const includePath of includePaths) {
|
|
93
|
-
const resolvedPath = sassPathResolver(url, includePath)
|
|
94
|
-
if (resolvedPath) return resolvedPath
|
|
134
|
+
const resolvedPath = sassPathResolver(url, includePath, infilePath)
|
|
135
|
+
if (resolvedPath && pathExists(resolvedPath.pathname)) return resolvedPath
|
|
95
136
|
}
|
|
96
137
|
return null
|
|
97
138
|
}
|