{"_id":"nextein","_rev":"168-1e0c9dc873e604713d4b93607707e48d","name":"nextein","description":"A static site and blog generator based on Next.js","dist-tags":{"latest":"4.3.0","beta":"4.0.0-beta.12"},"versions":{"0.0.0":{"name":"nextein","version":"0.0.0","description":"Saving this for a friend...","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"keywords":[],"author":"","license":"MIT","_id":"nextein@0.0.0","_shasum":"78bdc06af627df0340b9a2122bb6805401e0c509","_from":".","_npmVersion":"4.2.0","_nodeVersion":"7.10.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"shasum":"78bdc06af627df0340b9a2122bb6805401e0c509","tarball":"https://registry.npmjs.org/nextein/-/nextein-0.0.0.tgz","integrity":"sha512-AfpfQaNHi1wjvPeLAiKJz2y72nCI3E+P5NW7JmyWcNb8JS9FzE7hZ7B+I/BXFjX2ePvNlBISqcM75nIZj9Zd2A==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDhmw0MEoNvYSCoVd1IM0Rw+E8f+Tuyx6Q1pQk+yKL1BAIgW20wEJ+YR9bQw6YJddXQshDY4INFfJMsDxc58SZrnKA="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-0.0.0.tgz_1495984828270_0.9334647471550852"},"directories":{}},"1.0.0-beta1":{"name":"nextein","version":"1.0.0-beta1","description":"A Static Blog generator based in Next.js","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"fly","release":"fly release","prepublish":"npm run release"},"bin":{"nextein":"./dist/bin/nextein"},"files":["posts.js","post.js"],"dependencies":{"cross-spawn":"^5.1.0","enhanced-require":"^0.5.0-beta6","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark":"^7.0.1","remark-react":"^4.0.0","unfetch":"^2.1.2","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.0-beta","react":"^15.4.2","react-dom":"^15.4.2"},"devDependencies":{"babel-core":"^6.24.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","babili-webpack-plugin":"^0.1.1","fly":"2.0.6","fly-babel":"2.1.1","fly-clear":"1.0.1","fly-esnext":"2.0.1","fly-watch":"1.1.1"},"keywords":[],"author":"","license":"ISC","gitHead":"43c3317f2b2c14d61d6087edaa6d7155f3bca494","_id":"nextein@1.0.0-beta1","_npmVersion":"5.0.3","_nodeVersion":"8.0.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-SRhYkn3h58Gv28RMZruR4NxrG106RxE2k03/EPbe1bLhilif4GU/n77yOwJI0AHmLcUDgLdNfnYlC631MEeE0Q==","shasum":"088338fb2b2e3597db6bd1bfb6a96312cd2f61a0","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta1.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFNRe/Is+cT66bXBxMqQnKGODb/X8w2UBDBmURGu/ZDpAiEAmnCAnK5mrtOLM0Rzb0SjfVqfY3zeVJJ6M60hGS7LzZs="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta1.tgz_1497922891928_0.4163727657869458"},"directories":{}},"1.0.0-beta2":{"name":"nextein","version":"1.0.0-beta2","description":"A Static Blog generator based in Next.js","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"fly","release":"fly release","prepublish":"npm run release"},"bin":{"nextein":"./dist/bin/nextein"},"files":["posts.js","post.js"],"dependencies":{"cross-spawn":"^5.1.0","enhanced-require":"^0.5.0-beta6","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark":"^7.0.1","remark-react":"^4.0.0","unfetch":"^2.1.2","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.0-beta","react":"^15.4.2","react-dom":"^15.4.2"},"devDependencies":{"babel-core":"^6.24.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","babili-webpack-plugin":"^0.1.1","fly":"2.0.6","fly-babel":"2.1.1","fly-clear":"1.0.1","fly-esnext":"2.0.1","fly-watch":"1.1.1"},"keywords":[],"author":"","license":"ISC","gitHead":"43c3317f2b2c14d61d6087edaa6d7155f3bca494","_id":"nextein@1.0.0-beta2","_npmVersion":"5.0.3","_nodeVersion":"8.0.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-eQa+nAROcFkuDP85OH3gzw5Mezswl7REVadRFsgGGaSwH6oOpxeWRw8v5Gz+Wixlx7ekD9vkzMkAQ7uQlVdMSg==","shasum":"bab3b35552defe1e6d4768491ed811cbb6f01eed","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta2.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCUAemZqeP5Q7SuXrcVC7H9nGD6L/IiFAs2z8sJkt0LPAIgLP9M8nVMX23BBnZG1cJ6bGcY2W4b+YymsYt+6X3oUiQ="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta2.tgz_1497925930199_0.2481339897494763"},"deprecated":"Version unsupported. Please use latest going forward.","directories":{}},"1.0.0-beta3":{"name":"nextein","version":"1.0.0-beta3","description":"A Static Blog generator based in Next.js","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"fly","release":"fly release","prepublish":"npm run release"},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","posts.js","post.js"],"dependencies":{"cross-spawn":"^5.1.0","enhanced-require":"^0.5.0-beta6","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark":"^7.0.1","remark-react":"^4.0.0","unfetch":"^2.1.2","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.0-beta","react":"^15.4.2","react-dom":"^15.4.2"},"devDependencies":{"babel-core":"^6.24.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","babili-webpack-plugin":"^0.1.1","fly":"2.0.6","fly-babel":"2.1.1","fly-clear":"1.0.1","fly-esnext":"2.0.1","fly-watch":"1.1.1"},"keywords":[],"author":"","license":"ISC","gitHead":"43c3317f2b2c14d61d6087edaa6d7155f3bca494","_id":"nextein@1.0.0-beta3","_npmVersion":"5.0.3","_nodeVersion":"8.0.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-X7y6cy82b8kPSpWaB7n8am4eTNRWc9BxlbPwdg1E09F9wQKVqNdIXY0hL9Gsw6Vizp8rFKzUHLgbSbJUDGkh0w==","shasum":"9fb010539fe3a4018e785c36a27d156349717703","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta3.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDhujd4eZMbftqlVCrlcqxuyFSz3bqLu4WW97u8AEWU/AIhAJJSYuXKSxHUbM5nsaPss1SeI+rAYyIf8aENT9s7bSJ+"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta3.tgz_1497926376584_0.5283267125487328"},"directories":{}},"1.0.0-beta4":{"name":"nextein","version":"1.0.0-beta4","description":"A Static Blog generator based in Next.js","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"fly","release":"fly release","prepublish":"npm run release"},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","posts.js","post.js"],"dependencies":{"cross-spawn":"^5.1.0","enhanced-require":"^0.5.0-beta6","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark":"^7.0.1","remark-react":"^4.0.0","unfetch":"^2.1.2","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.0-beta","react":"^15.4.2","react-dom":"^15.4.2"},"devDependencies":{"babel-core":"^6.24.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","babili-webpack-plugin":"^0.1.1","fly":"2.0.6","fly-babel":"2.1.1","fly-clear":"1.0.1","fly-esnext":"2.0.1","fly-watch":"1.1.1"},"keywords":[],"author":"","license":"ISC","gitHead":"43c3317f2b2c14d61d6087edaa6d7155f3bca494","_id":"nextein@1.0.0-beta4","_npmVersion":"5.0.3","_nodeVersion":"8.0.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-M+XDZz4M+va7OaSa8wIreReLC1g9QbvB8axChynJDXj3q9NJLWEgtA+MKoCRzwiuvLoeG2zCSrZRqWb8FhFo9w==","shasum":"33e45eafbbfc12ca175834d7c24591f849846fb1","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta4.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDwvfyIl80poIBBcIZYHK2EJMhr7xi2SF4KuamLOxAxpwIhANPLulLs3kQDlZGHOh7lH3yZLV+mY/+DabgdkTx7BPfA"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta4.tgz_1497926685648_0.7665138456504792"},"directories":{}},"1.0.0-beta5":{"name":"nextein","version":"1.0.0-beta5","description":"A Static Blog generator based in Next.js","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"fly","release":"fly release","prepublish":"npm run release"},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","posts.js","post.js"],"dependencies":{"babili-webpack-plugin":"^0.1.1","cross-spawn":"^5.1.0","enhanced-require":"^0.5.0-beta6","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark":"^7.0.1","remark-react":"^4.0.0","unfetch":"^2.1.2","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.0-beta","react":"^15.4.2","react-dom":"^15.4.2"},"devDependencies":{"babel-core":"^6.24.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","fly":"2.0.6","fly-babel":"2.1.1","fly-clear":"1.0.1","fly-esnext":"2.0.1","fly-watch":"1.1.1"},"keywords":[],"author":"","license":"ISC","gitHead":"43c3317f2b2c14d61d6087edaa6d7155f3bca494","_id":"nextein@1.0.0-beta5","_npmVersion":"5.0.3","_nodeVersion":"8.0.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-pJ4D1KNGlSbpKxCsbpinCosAgiUpvAJhBFTb0CYoLwbmTqYRD2s67TOuG0g9QJ5fzkCWWlrNWHnzYRyBFTsT7w==","shasum":"c52183473eea074e5885aee366e52b94712b1215","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta5.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGJy/rLZY3kGhYLAXE3Gu6YWmjBLWY2lha+J/nzFow0YAiAhq6wRQaG3yRH9HUODgdu06S3Ifvmo3yhOf6/8mDyJ+Q=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta5.tgz_1497926783468_0.45002214005216956"},"directories":{}},"1.0.0-beta6":{"name":"nextein","version":"1.0.0-beta6","description":"A Static Blog generator based in Next.js","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"fly","release":"fly release","prepublish":"npm run release"},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","posts.js","post.js"],"dependencies":{"babili-webpack-plugin":"^0.1.1","cross-spawn":"^5.1.0","enhanced-require":"^0.5.0-beta6","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark":"^7.0.1","remark-react":"^4.0.0","unfetch":"^2.1.2","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.0-beta","react":"^15.4.2","react-dom":"^15.4.2"},"devDependencies":{"babel-core":"^6.24.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","fly":"2.0.6","fly-babel":"2.1.1","fly-clear":"1.0.1","fly-esnext":"2.0.1","fly-watch":"1.1.1"},"keywords":[],"author":"","license":"ISC","gitHead":"43c3317f2b2c14d61d6087edaa6d7155f3bca494","_id":"nextein@1.0.0-beta6","_npmVersion":"5.0.3","_nodeVersion":"8.0.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-MhdfbTUBrH7tXG77P1bSoMUS5vqkoNT3SxBVYbUa5DBGkhXW9ygqWchS1Fvwd7hYWRe6353mkztbmt7tklm2Kw==","shasum":"fc43fe889436c7d4cc4bfe06eaa5956f4d28c9b0","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta6.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBfo2ChZZCJtwozXr8UohPWlepn+gBDXRncWXwJGR82WAiEAsuQMvPFgwd1c7Ftdz1mfRyhABjoNEVYttjEkwnfyL0Q="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta6.tgz_1497926952575_0.9124480148311704"},"directories":{}},"1.0.0-beta7":{"name":"nextein","version":"1.0.0-beta7","description":"A Static Blog generator based in Next.js","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"fly","release":"fly release","prepublish":"npm run release"},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","posts.js","post.js"],"dependencies":{"babili-webpack-plugin":"^0.1.1","cross-spawn":"^5.1.0","enhanced-require":"^0.5.0-beta6","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark":"^7.0.1","remark-react":"^4.0.0","unfetch":"^2.1.2","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.0-beta","react":"^15.4.2","react-dom":"^15.4.2"},"devDependencies":{"babel-core":"^6.24.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","fly":"2.0.6","fly-babel":"2.1.1","fly-clear":"1.0.1","fly-esnext":"2.0.1","fly-watch":"1.1.1"},"keywords":[],"author":"","license":"ISC","gitHead":"3b0ce170a713463ce6f8e26388af6457f12d0d3d","_id":"nextein@1.0.0-beta7","_npmVersion":"5.0.3","_nodeVersion":"8.0.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-M0HqMLoyVGL0KS8IcmVRflMlRTv5TcOOAFkp5buk4rPgGrQC/akok0qEEud6FDNsxAAJCZ4ipzJwW/rlBSwLNg==","shasum":"f2fb5beb5a2e8de2a30d449be293166d122c2f97","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta7.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDdZ4tzp+BSGS4ulMao5hR9B1sLRWxvuBnRkgYYTckpVwIgCFUs06mbJgESnrdrgP8Dw2ugR9XBw1rMT9NJoIL2WkE="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta7.tgz_1498002694647_0.48271191073581576"},"directories":{}},"1.0.0-beta8":{"name":"nextein","version":"1.0.0-beta8","description":"A static site generator based in Next.js","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"fly","release":"fly release","prepublish":"npm run release"},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","posts.js","post.js"],"dependencies":{"babili-webpack-plugin":"^0.1.1","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark":"^7.0.1","remark-react":"^4.0.0","unfetch":"^2.1.2","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.0-beta","react":"^15.4.2","react-dom":"^15.4.2"},"devDependencies":{"babel-core":"^6.24.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","fly":"2.0.6","fly-babel":"2.1.1","fly-clear":"1.0.1","fly-esnext":"2.0.1","fly-watch":"1.1.1"},"keywords":[],"author":"","license":"ISC","gitHead":"6762543b47646ca467d6f13f72a4dbe10cf74816","_id":"nextein@1.0.0-beta8","_npmVersion":"5.0.3","_nodeVersion":"8.0.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-tAxbCz5SE27xo4OrB/+VcQSl3BVU+AbrWpReHPbFDB/yJx375+UfuCwTNSsq+VtswCXYNSwnasz3E+dv3pvgxw==","shasum":"c451fdef5e2b243e8068d1bd2fa3bc10d16b15cd","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta8.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDW5j0BJ9N5ufNfGo14+/0qbyf1FZOazrP+cPZOuWaUjwIhAOtbMmowyEdR4ZoG+uJPCZ9qiwncZ0wy7lB04bQCKQQ/"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta8.tgz_1498253369397_0.6552110791672021"},"directories":{}},"1.0.0-beta9":{"name":"nextein","version":"1.0.0-beta9","description":"A static site generator based in Next.js","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"fly","release":"fly release","prepublish":"npm run release"},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","posts.js","post.js"],"dependencies":{"babili-webpack-plugin":"^0.1.1","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark":"^7.0.1","remark-react":"^4.0.0","unfetch":"^2.1.2","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.1-beta","react":"^15.6.1","react-dom":"^15.6.1"},"devDependencies":{"babel-core":"^6.24.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","fly":"2.0.6","fly-babel":"2.1.1","fly-clear":"1.0.1","fly-esnext":"2.0.1","fly-watch":"1.1.1"},"keywords":[],"author":"","license":"ISC","gitHead":"900bc6bf33e6be2132670bac8d9c7cb77ae08fa3","_id":"nextein@1.0.0-beta9","_npmVersion":"5.0.3","_nodeVersion":"8.0.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-LNyCmyp+gskYaKsB1zTxJQ6r14RkASG50YaNyAVDJKdbNGt3lhMjiE/0zKr/pMIKitzVoE5xo/gtnUsPi2ncCQ==","shasum":"83377b1f4ac2511dbef3d7c8928b2d7b512ff5a5","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta9.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCGKVFj17sOC2RKkMrx+osVYWwtToWzmlGUKBZK12r4dgIgH51ZxyeopbWA1XieunvI3RX093BQ94n8VEShbDKgyfE="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta9.tgz_1498413970019_0.05423199059441686"},"directories":{}},"1.0.0-beta10":{"name":"nextein","version":"1.0.0-beta10","description":"A static site generator based in Next.js","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"fly","release":"fly release","prepublish":"npm run release"},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","posts.js","post.js"],"dependencies":{"babili-webpack-plugin":"^0.1.1","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark":"^7.0.1","remark-react":"^4.0.0","unfetch":"^2.1.2","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.1-beta","react":"^15.6.1","react-dom":"^15.6.1"},"devDependencies":{"babel-core":"^6.24.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","fly":"2.0.6","fly-babel":"2.1.1","fly-clear":"1.0.1","fly-esnext":"2.0.1","fly-watch":"1.1.1"},"keywords":[],"author":"","license":"ISC","gitHead":"48029e300f31efcd79d7a7254b7f2110c8c8280b","_id":"nextein@1.0.0-beta10","_npmVersion":"5.0.4","_nodeVersion":"8.0.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-aL1ls7vIP+dkmoQnxQdv0ox9sPMZkmIHkyatVNsCEWDq/vtIaKb1qV4bWTlb3vY7tPYQ5p5HiPXcLvLVWidRJw==","shasum":"9a676f55b7f9c3ae760ded0acb8d72ac5a6e6b19","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta10.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHSlTi9FdPIUscfA1e3FU/7O6oOkzzMdTvTf82Lf0SQxAiEAqXZfn/8fRdPCAe/B9br06GiW6oYrladq3g98kjbpHn8="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta10.tgz_1498613707249_0.957091307034716"},"directories":{}},"1.0.0-beta11":{"name":"nextein","version":"1.0.0-beta11","description":"A static site generator based in Next.js","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"fly","release":"fly release","prepublish":"npm run release"},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","posts.js","post.js"],"dependencies":{"babili-webpack-plugin":"^0.1.1","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark":"^7.0.1","remark-react":"^4.0.0","unfetch":"^2.1.2","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.1-beta","react":"^15.6.1","react-dom":"^15.6.1"},"devDependencies":{"babel-core":"^6.24.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","fly":"2.0.6","fly-babel":"2.1.1","fly-clear":"1.0.1","fly-esnext":"2.0.1","fly-watch":"1.1.1"},"keywords":[],"author":"","license":"ISC","gitHead":"3771bae1d4429e0048265f222e422207502746f8","_id":"nextein@1.0.0-beta11","_npmVersion":"5.0.4","_nodeVersion":"8.0.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-q8RLbEO2MbdXefkfDQTDYnrnIsyT42dYJqk0nNU4yZKSVn7c2m3IwEBesy3gFCgpVnCeO+G9pOW//RAQVqiQdA==","shasum":"a324c0f581145a3c813ca021bbd95ab27bb4465d","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta11.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDfUBF5QpIY+YDbv0IgjQTopWT8PLpwv0pdyd5N9jZNhgIgFKwiXNvE+ApunF48pQ68q3a0w1XMQr3SsCGzsktXYpU="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta11.tgz_1498764138307_0.8996617053635418"},"directories":{}},"1.0.0-beta12":{"name":"nextein","version":"1.0.0-beta12","description":"A static site generator based in Next.js","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"taskr","release":"taskr release","prepublish":"npm run release"},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","posts.js","post.js"],"dependencies":{"babili-webpack-plugin":"^0.1.1","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark":"^7.0.1","remark-react":"^4.0.0","unfetch":"^2.1.2","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.1-beta","react":"^15.6.1","react-dom":"^15.6.1"},"devDependencies":{"babel-core":"^6.24.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","taskr":"1.0.6","@taskr/babel":"1.0.6","@taskr/clear":"1.0.6","@taskr/esnext":"1.0.0","@taskr/watch":"1.0.6"},"keywords":[],"author":"","license":"ISC","gitHead":"478ee6be10475724c913b70bbd63b1a51e77ad50","_id":"nextein@1.0.0-beta12","_npmVersion":"5.0.4","_nodeVersion":"8.0.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-MSyyRfhCG0MUZskU926It7JMnM606uRVUsup+BZ1SGH+lSZg3r2rxQyL70Jk8n9eMDiWxElQJHYRy5OPQqROHA==","shasum":"505b31944ba9dea7c5a87de10c85e178dc1ae353","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta12.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCZcHuPZ1VCm/KE+4qMqqJP/Gv1kJRIooNqLWaZXfbHTQIhAN8k5H68awPB6UAwuEGf1EROLDLycdZcu2pHTrr/d/MI"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta12.tgz_1499029690356_0.4585121301934123"},"directories":{}},"1.0.0-beta13":{"name":"nextein","version":"1.0.0-beta13","description":"A static site generator based in Next.js","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"taskr","release":"taskr release","prepublish":"npm run release"},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","posts.js","post.js"],"dependencies":{"babili-webpack-plugin":"^0.1.1","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark":"^7.0.1","remark-react":"^4.0.0","unfetch":"^2.1.2","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.1-beta","react":"^15.6.1","react-dom":"^15.6.1"},"devDependencies":{"@taskr/babel":"1.0.6","@taskr/clear":"1.0.6","@taskr/esnext":"1.0.0","@taskr/watch":"1.0.6","babel-core":"^6.24.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","next":"3.0.1-beta.13","react":"^15.6.1","react-dom":"^15.6.1","taskr":"1.0.6"},"keywords":[],"author":"","license":"ISC","gitHead":"72b9316d6533681a606791286bc7cdfa3870a38d","_id":"nextein@1.0.0-beta13","_npmVersion":"5.1.0","_nodeVersion":"8.0.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-OdG338bphGuVxSPVvxenHQaacMzqsdUWOfzv+nTysbAV+CsfGRxV6PGxtCROuxOGYI3/feE47xYkHn1M518J1A==","shasum":"29e81a1ec6f434577768079735e95e9845807523","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta13.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHRVC9K/5I8vkvIalLGlKw3UVBgsjaVMG3zckvwT8Eh4AiADJAWLO9Fh5rj7QUW1eMwmmFkFuIJQ54X3T/Uj4O1yUg=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta13.tgz_1499641072466_0.5358399106189609"},"directories":{}},"1.0.0-beta14":{"name":"nextein","version":"1.0.0-beta14","description":"A static site generator based in Next.js","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","posts.js","post.js"],"dependencies":{"babili-webpack-plugin":"^0.1.1","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark":"^7.0.1","remark-react":"^4.0.0","unfetch":"^2.1.2","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.1-beta","react":"^15.6.1","react-dom":"^15.6.1"},"devDependencies":{"@taskr/babel":"1.0.6","@taskr/clear":"1.0.6","@taskr/esnext":"1.0.0","@taskr/watch":"1.0.6","babel-core":"^6.24.1","babel-eslint":"7.2.3","babel-jest":"20.0.3","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"20.0.4","next":"3.0.1-beta.18","react":"^15.6.1","react-dom":"^15.6.1","standard":"10.0.2","taskr":"1.0.6","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":[],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"cdf6f30ce3b979d22dc8977a4dd9e64b6fed5237","_id":"nextein@1.0.0-beta14","_npmVersion":"5.3.0","_nodeVersion":"8.0.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-SoETQC4Gs0W89zugGVCeAnB1WuRvEli+RcgPAlMAERyPwcIsTEJm/7rlVuYnf2QxdTd7Mt7bDRaNxQIvwEiXew==","shasum":"d04e2ea1b0e4bf375930860f656377aa77d06efd","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta14.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDEqTFkd1RysMFNdmqLXiv4VbbkUMwOXRn5/gk9pw19cgIgHcTMGUbbI7qff/YIWExQe+k6isndgUg2lzX+u59uF+M="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta14.tgz_1500836972408_0.5868525891564786"},"directories":{}},"1.0.0-beta15":{"name":"nextein","version":"1.0.0-beta15","description":"A static site generator based in Next.js","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","posts.js","post.js"],"dependencies":{"babili-webpack-plugin":"^0.1.1","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark":"^7.0.1","remark-react":"^4.0.0","unfetch":"^2.1.2","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.1-beta","react":"^15.6.1","react-dom":"^15.6.1"},"devDependencies":{"@taskr/babel":"1.0.6","@taskr/clear":"1.0.6","@taskr/esnext":"1.0.0","@taskr/watch":"1.0.6","babel-core":"^6.24.1","babel-eslint":"7.2.3","babel-jest":"20.0.3","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"20.0.4","next":"3.0.1-beta.18","react":"^15.6.1","react-dom":"^15.6.1","standard":"10.0.2","taskr":"1.0.6","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":[],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"97bc381a928ab6fcb8ebf85e57b3185105583aa9","_id":"nextein@1.0.0-beta15","_npmVersion":"5.3.0","_nodeVersion":"8.0.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-TkdM0YzKSntr5QLoSAECyuz/DkektUpJDj8tl2Ufm/ujaLm2NJ9S3xaCxqj8uK+TxrrXEePU2X7VcROB9n4Wxg==","shasum":"2a5614eb5a0a2393fdf09c290fdee0e1c6a3ee3c","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta15.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDsdKCl5DzatWGOFFLImrNYY4Ww6OkMzh8L60TJ2LFtaAiBwpucoLoCV0cUj/JUE99mXnB57y11j8PbFxSWh3GhYww=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta15.tgz_1500839380211_0.7030371285509318"},"directories":{}},"1.0.0-beta16":{"name":"nextein","version":"1.0.0-beta16","description":"A static site generator based in Next.js","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","posts.js","post.js"],"dependencies":{"babili-webpack-plugin":"^0.1.1","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark":"^7.0.1","remark-react":"^4.0.0","unfetch":"^2.1.2","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.1-beta","react":"^15.6.1","react-dom":"^15.6.1"},"devDependencies":{"@taskr/babel":"1.0.6","@taskr/clear":"1.0.6","@taskr/esnext":"1.0.0","@taskr/watch":"1.0.6","babel-core":"^6.24.1","babel-eslint":"7.2.3","babel-jest":"20.0.3","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"20.0.4","next":"3.0.1-beta.18","react":"^15.6.1","react-dom":"^15.6.1","react-test-renderer":"15.6.1","standard":"10.0.2","taskr":"1.0.6","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":[],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"f09b89dfb668c3a9b595e28421a75b889c9d6a67","_id":"nextein@1.0.0-beta16","_npmVersion":"5.3.0","_nodeVersion":"8.0.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-MRicu1+VxhMQN8kpTRhS4Zhanyc5YXi5uZZUDcBX8ZDYDVu4N2FqDUJX1kK2Y3U12vCu0nXKV3oGo/EQUJ9CqA==","shasum":"0483fd2e288f35f65685b1465a377fd005dcc30e","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta16.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCEfGPs6CKyx3NQYHOEHPHCVpxtMv/42aOw4/YQsU1jiQIgLQNihCnPpoZlaSLd8mHg5ouO8b+v0NIyJ5MK5L+Ujq0="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta16.tgz_1501547344297_0.28343470650725067"},"directories":{}},"1.0.0-beta17":{"name":"nextein","version":"1.0.0-beta17","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","posts.js","post.js"],"dependencies":{"babili-webpack-plugin":"^0.1.1","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark-parse":"4.0.0","remark-react":"^4.0.0","unfetch":"^2.1.2","unified":"6.1.5","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.3","react":"^15.6.1","react-dom":"^15.6.1"},"devDependencies":{"@taskr/babel":"1.0.6","@taskr/clear":"1.0.6","@taskr/esnext":"1.0.0","@taskr/watch":"1.0.6","babel-core":"^6.24.1","babel-eslint":"7.2.3","babel-jest":"20.0.3","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"20.0.4","next":"3.0.3","react":"^15.6.1","react-dom":"^15.6.1","react-test-renderer":"15.6.1","standard":"10.0.2","taskr":"1.0.6","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"aaead4b87bc6e561fc3fcb22f00b491d241e503b","_id":"nextein@1.0.0-beta17","_npmVersion":"5.3.0","_nodeVersion":"8.0.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-X1f+gay+CaXHcoBWPN+qJG/OD1UbG6XXy8BcA2NOUPefHIxgbSZi74gaTOZ1EftBlKrazrWYUM8yBFwNm+Si/w==","shasum":"fd9e3dc4b6a4216fa8a90c19641b31763cb4e4e7","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta17.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIES3JhReL+rvm/xkRh0xgTtRNm/2M/gag4YXMi88SxjnAiEA1g286SvaaCrjH1v3bNZZ2WMH3nNbkZcuyKcDWgMrpOo="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta17.tgz_1502312958974_0.05568950925953686"},"directories":{}},"1.0.0-beta18":{"name":"nextein","version":"1.0.0-beta18","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"babili-webpack-plugin":"^0.1.1","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark-parse":"4.0.0","remark-react":"^4.0.0","unfetch":"^2.1.2","unified":"6.1.5","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.3","react":"^15.6.1","react-dom":"^15.6.1"},"devDependencies":{"@taskr/babel":"1.0.6","@taskr/clear":"1.0.6","@taskr/esnext":"1.0.0","@taskr/watch":"1.0.6","babel-core":"^6.24.1","babel-eslint":"7.2.3","babel-jest":"20.0.3","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"20.0.4","next":"3.0.3","react":"^15.6.1","react-dom":"^15.6.1","react-test-renderer":"15.6.1","standard":"10.0.2","taskr":"1.0.6","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"af57f6c71f890e17a3959510c126a218fb069f2c","_id":"nextein@1.0.0-beta18","_npmVersion":"5.3.0","_nodeVersion":"8.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-fC5G8Cuwcpp0xIvIAGOkGo6cE2RdjiLBDY/PfySOaS2KFoycWPyGRt1mQZ0yiLJdJkD9gWscI1p1thz3eXROog==","shasum":"dca74ff08aa97a5058853f6d19c38d2dc316dad1","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta18.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDR8Sv0ApXcbuUnDRnxsk/kw4xSMmYsgBm9bIar/1224AIgGA/2uKNIDJj56zJARL/fG8PX4rRUICGbzHu0KVcJjHo="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta18.tgz_1502597787053_0.5151876599993557"},"directories":{}},"1.0.0-beta19":{"name":"nextein","version":"1.0.0-beta19","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"babili-webpack-plugin":"^0.1.1","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","pkg-up":"^2.0.0","remark-parse":"4.0.0","remark-react":"^4.0.0","unfetch":"^2.1.2","unified":"6.1.5","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.3","react":"^15.6.1","react-dom":"^15.6.1"},"devDependencies":{"@taskr/babel":"1.0.6","@taskr/clear":"1.0.6","@taskr/esnext":"1.0.0","@taskr/watch":"1.0.6","babel-core":"^6.24.1","babel-eslint":"7.2.3","babel-jest":"20.0.3","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"20.0.4","next":"3.0.3","react":"^15.6.1","react-dom":"^15.6.1","react-test-renderer":"15.6.1","standard":"10.0.2","taskr":"1.0.6","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"46e4be169d6b3f4e8cc6d3fb14c76e382472ab21","_id":"nextein@1.0.0-beta19","_npmVersion":"5.3.0","_nodeVersion":"8.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-wWOB8H/M5ZgqdB32GmenHS3VoOfhRI4rfRSpFbhr7F6nsPgTz3S3zH3pLEqraisXoaNjAnVO156R7SOyxzneQw==","shasum":"6545592650493d203f621f332f02c7b3f3612cb1","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta19.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCACxE7K1MlK9P1qPpCBLXo+hXt5JhRiZpsUaKU1fONMwIgBnY4Zh6xcQF299tOgfhLfHqmo8Jyn/VwZXzi6NAPy6Q="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta19.tgz_1503018343221_0.17394366790540516"},"directories":{}},"1.0.0-beta20":{"name":"nextein","version":"1.0.0-beta20","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"babili-webpack-plugin":"^0.1.1","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.0.0","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.1","remark-parse":"4.0.0","remark-rehype":"2.0.1","unfetch":"^2.1.2","unified":"6.1.5","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.3","react":"^15.6.1","react-dom":"^15.6.1"},"devDependencies":{"@taskr/babel":"1.0.6","@taskr/clear":"1.0.6","@taskr/esnext":"1.0.0","@taskr/watch":"1.0.6","babel-core":"^6.24.1","babel-eslint":"7.2.3","babel-jest":"20.0.3","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"21.0.1","next":"3.2.1","react":"^15.6.1","react-dom":"^15.6.1","react-test-renderer":"15.6.1","standard":"10.0.2","taskr":"1.0.6","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"c36898ac80cf309a971632e6f7eb9c2935bbb3f0","_id":"nextein@1.0.0-beta20","_npmVersion":"5.3.0","_nodeVersion":"8.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-eKvprBcYGS2XZP3hTOHUB8rLavDbGz/FpdHpNp3g2jQ62uStc9r904l9n2vN6MIV5fLGrlv+DRyQTS5Wvtutdw==","shasum":"549675cec8fdb5235e9605aa11389141e934bd97","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta20.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDl5OhH5Dbg4aH/eRy/qD8PKfZwHoy+AQVDDpKWOT8asAiA7jd2sW83at4TA4ARDlDEBE+hrLJY2TDkmkBSdix16pQ=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta20.tgz_1504823906862_0.17093735677190125"},"directories":{}},"1.0.0-beta21":{"name":"nextein","version":"1.0.0-beta21","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"babili-webpack-plugin":"^0.1.1","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.0.0","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.1","remark-parse":"4.0.0","remark-rehype":"2.0.1","unfetch":"^2.1.2","unified":"6.1.5","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.3","react":"^15.6.1","react-dom":"^15.6.1"},"devDependencies":{"@taskr/babel":"1.0.6","@taskr/clear":"1.0.6","@taskr/esnext":"1.0.0","@taskr/watch":"1.0.6","babel-core":"^6.24.1","babel-eslint":"7.2.3","babel-jest":"20.0.3","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"21.0.1","next":"3.2.1","react":"^15.6.1","react-dom":"^15.6.1","react-test-renderer":"15.6.1","standard":"10.0.2","taskr":"1.0.6","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"5a89baefecbcff2179a806ce37289ab2c72b5eaf","_id":"nextein@1.0.0-beta21","_npmVersion":"5.3.0","_nodeVersion":"8.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-zinjC+o3QSQMnuZoRQeQJKahvjmTETwSLkRwa4g3ToxJVkzf9zyV5CBYWx6XfwB8uZ/NBW25d4P2OJ1aWL1pFg==","shasum":"1a85a090640f796a7400eba4ff7a7838c337b5c1","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta21.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDTBgi0PhgwcJIfo3+PmsJ74iBPKXPkKMp7eBe/JjE6ZgIhAOehW7DkOvy9sdPi+bSCNqSNzNHEWOi1x4qMYvA9XWKe"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta21.tgz_1505784258421_0.6091397781856358"},"directories":{}},"1.0.0-beta22":{"name":"nextein","version":"1.0.0-beta22","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"babel-minify-webpack-plugin":"^0.2.0","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.0.0","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.1","remark-parse":"4.0.0","remark-rehype":"2.0.1","unfetch":"^2.1.2","unified":"6.1.5","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.3","react":"^15.6.1","react-dom":"^15.6.1"},"devDependencies":{"@taskr/babel":"1.0.6","@taskr/clear":"1.0.6","@taskr/esnext":"1.0.0","@taskr/watch":"1.0.6","babel-core":"^6.24.1","babel-eslint":"7.2.3","babel-jest":"20.0.3","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"21.0.1","next":"3.2.1","react":"^15.6.1","react-dom":"^15.6.1","react-test-renderer":"15.6.1","standard":"10.0.2","taskr":"1.0.6","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"5fc2e0e23f892d500126603d8250c04649256bb1","_id":"nextein@1.0.0-beta22","_npmVersion":"5.4.2","_nodeVersion":"8.6.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-3AEkjrNmrA7SHgDsfYJGydaoAmZ5TVe4G3DBbn8LGYFWpAJtPYRSZ6ML2IHApAQnynhsxe1moLW+RfTdWIuV7Q==","shasum":"ee140e7f6578dafb21d55b1c1dcecac1ae34b623","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta22.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBZPint66gTuv+jRHgh2yeY4FKej+Z7glUCWhDAIzRpDAiANB6mJbkAJ7f649eGfPj8xyP5HxkyD3U/BjhCY1rTkVg=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta22.tgz_1506970495659_0.4172933059744537"},"directories":{}},"1.0.0-beta23":{"name":"nextein","version":"1.0.0-beta23","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"babel-minify-webpack-plugin":"^0.2.0","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.0.0","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.1","remark-parse":"4.0.0","remark-rehype":"2.0.1","unfetch":"^2.1.2","unified":"6.1.5","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^3.0.3","react":"^15.6.1","react-dom":"^15.6.1"},"devDependencies":{"@taskr/babel":"1.0.6","@taskr/clear":"1.0.6","@taskr/esnext":"1.0.0","@taskr/watch":"1.0.6","babel-core":"^6.24.1","babel-eslint":"7.2.3","babel-jest":"20.0.3","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.23.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"21.0.1","next":"3.2.1","react":"^15.6.1","react-dom":"^15.6.1","react-test-renderer":"15.6.1","standard":"10.0.2","taskr":"1.0.6","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"a89582bc122e7ad3bd2f474675786d64db95fc0b","_id":"nextein@1.0.0-beta23","_npmVersion":"5.4.2","_nodeVersion":"8.6.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-PKXGGqTMONyh6+RXwKv+E1074beAxxG1sYfrpKEHOCUn9pOOCG2KxZ3zlDmvghSlPb6IfO+kLfeNT/ZpDC9b3w==","shasum":"5e303d0b96906d1d16ed8b15111820cdfb0bfec3","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta23.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDlK1csvdKLKy3rJQUsJbH+IbOLtqZJNzxzOXM/zHhPYwIgH1BUjwXzzAtrVDkc4ZPF6YcRE2Q93aSdGhZyIGv5Mds="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta23.tgz_1507236833713_0.704728830140084"},"directories":{}},"1.0.0-beta24":{"name":"nextein","version":"1.0.0-beta24","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"babel-minify-webpack-plugin":"^0.2.0","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.0.0","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.1","remark-parse":"4.0.0","remark-rehype":"2.0.1","unfetch":"^3.0.0","unified":"6.1.5","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"4.0.1","react":"16.0.0","react-dom":"16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.0.1","babel-jest":"21.2.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"21.2.1","next":"4.0.1","react":"16.0.0","react-dom":"16.0.0","react-test-renderer":"16.0.0","standard":"10.0.3","taskr":"1.1.0","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"a42d46d77fdfa7aef73b6c966beb7cc0ba4cd346","_id":"nextein@1.0.0-beta24","_npmVersion":"5.4.2","_nodeVersion":"8.6.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-I7ck3iZ9Uzwtd6k6pkyaKT6UxJ5muE2HExFwClOeBwLPdEFclYwKGGR3c3q5t63gqe3G4SDcOj8W8TJjmBCNWA==","shasum":"f6a7c510f8552ed6a69cf2fc7c42e6810a7b8e3d","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta24.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC+KFec98j6CMk1Jkq5C0dHva+gwrcfBSNnDa/1dTmbTwIgXetgy3Xnv9Eyc8tDDsgMtrCjXWTFdt8jbtZJnFsETLE="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta24.tgz_1507650245376_0.10746484599076211"},"directories":{}},"1.0.0-beta25":{"name":"nextein","version":"1.0.0-beta25","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.1.0","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.1","remark-parse":"4.0.0","remark-rehype":"2.0.1","uglifyjs-webpack-plugin":"1.0.1","unfetch":"^3.0.0","unified":"6.1.5","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^4.0.1","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.0.1","babel-jest":"21.2.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"21.2.1","next":"4.1.4","react":"16.0.0","react-dom":"16.0.0","react-test-renderer":"16.0.0","standard":"10.0.3","taskr":"1.1.0","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"75ab3dfe732bac0e8f8c69221fb850bd43ec0aa1","_id":"nextein@1.0.0-beta25","_npmVersion":"5.4.2","_nodeVersion":"8.7.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-2BSjp0nHhf45ijjVKf6NGcSeJc4BGEsvXfjvhaeOyVqQ2W6vK+Ep7DtZA0+XoT7gXPL9k72ISEgNvuFLSA9nvQ==","shasum":"c231aebcd573c5471f928444b5a3c5c9e76d2258","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta25.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDEHBI0w2tsUw7As0G5FyRoGx+TUo42zMH4EByQfeGgHwIhANg8pR+FhREF1wVT9E9w0ZaCN2c0SDvuyWyPVg3KKt/j"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta25.tgz_1509375866402_0.5470538404770195"},"directories":{}},"1.0.0-beta26":{"name":"nextein","version":"1.0.0-beta26","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"1.7.0","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.1.0","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.1","remark-parse":"4.0.0","remark-rehype":"2.0.1","uglifyjs-webpack-plugin":"1.0.1","unfetch":"^3.0.0","unified":"6.1.5","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^4.0.1","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.0.2","babel-jest":"21.2.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"21.2.1","next":"4.1.4","react":"16.1.1","react-dom":"16.1.1","react-test-renderer":"16.1.1","standard":"10.0.3","taskr":"1.1.0","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"0a1f25eed445308ea3deb55997ebeafd6cea2432","_id":"nextein@1.0.0-beta26","_npmVersion":"5.4.2","_nodeVersion":"8.7.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-qcD7w3EfU3hMrgXaGPXIshwUCrUD9wunsQ4jJcWsVCM5r9fT1H/YuvjG/fcv0mB+Erc9ssl6rxyDYSVCUMHQwg==","shasum":"3d2ebc4bf5ca3887991dd7a9c6779ecbb1427002","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta26.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDzr0D5Fdij1HQcA1PZ7bgpwlHeCLQmBnEXpfzgnMHUxgIgEdfOO7nu26diCn05nY9Mzc3wZ/EKN8k49Qa0OK2eMlQ="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta26.tgz_1510682989820_0.0671319596003741"},"directories":{}},"1.0.0-beta27":{"name":"nextein","version":"1.0.0-beta27","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"1.7.0","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.1.0","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.1","remark-parse":"4.0.0","remark-rehype":"2.0.1","uglifyjs-webpack-plugin":"1.0.1","unfetch":"^3.0.0","unified":"6.1.5","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^4.0.1","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.0.2","babel-jest":"21.2.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"21.2.1","next":"4.1.4","react":"16.1.1","react-dom":"16.1.1","react-test-renderer":"16.1.1","standard":"10.0.3","taskr":"1.1.0","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"40d5b731d4c458e4c2de8647ea7a3d579dd20d94","_id":"nextein@1.0.0-beta27","_npmVersion":"5.4.2","_nodeVersion":"8.7.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-3vLXgO/NmUHwnD367QmfVaoVLiq49KoZ+s5RV6eIwzsBFlJD4CXjChD29QXG0CXN1UkiOjmwnleqnHaoz9iBmg==","shasum":"ac90db53767deeda816553ee8e0a89581fdeff94","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0-beta27.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDS9PTonM9nBRNt8kNCV1+UuNFDWxGDa7d6M3hm9nbFdwIgMk6tebOMG6j9FxlFrGaqeYgMrpSLHTVbvxbW5Sovgpc="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0-beta27.tgz_1510768213150_0.5290061640553176"},"directories":{}},"1.0.0":{"name":"nextein","version":"1.0.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"1.7.0","cross-spawn":"^5.1.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.1.0","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.1","remark-parse":"4.0.0","remark-rehype":"2.0.1","uglifyjs-webpack-plugin":"1.0.1","unfetch":"^3.0.0","unified":"6.1.5","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^4.0.1","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.0.2","babel-jest":"21.2.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"21.2.1","next":"4.1.4","react":"16.1.1","react-dom":"16.1.1","react-test-renderer":"16.1.1","standard":"10.0.3","taskr":"1.1.0","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"40d5b731d4c458e4c2de8647ea7a3d579dd20d94","_id":"nextein@1.0.0","_npmVersion":"5.4.2","_nodeVersion":"8.7.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-+MrIu6gfN47PfcOAbrhSDoZxe1si6pbe8Bo0cz4kbvTMNxwHXmf9zS6azdU6OTRTSdSABSz3+sj/Ov6a84V9jA==","shasum":"82627c5c9bab5a5afc895f6f174748fe62da01fa","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.0.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFcX7I1ZrVPcsNQ4oleRNy1pHVa7GN+CuOhla3CNC/ARAiAea1Ra3QuW4opdsYZTxUgulPqY8WCtPt1eMAMy1HXkMw=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.0.0.tgz_1511654357820_0.24296020553447306"},"directories":{}},"1.1.0":{"name":"nextein","version":"1.1.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.0","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.1.0","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.1.8","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^4.0.1","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.1","babel-jest":"22.1.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"22.1.4","next":"4.2.3","react-dom":"16.2.0","react":"16.2.0","react-test-renderer":"16.2.0","standard":"10.0.3","taskr":"1.1.0","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"cdb290e6b7f945d48281eefb8ad1666b17853dd6","_id":"nextein@1.1.0","_npmVersion":"5.6.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-xwV0+k7Tx2kQ/WDcjN2J6OhYsw8bqYOg1XTbBBGeGf8Q0aGMsGhtchSZT1srxJAJllqU1POe2rQwUKDYG1vDUw==","shasum":"3560e14433dab5be73077cda4c4cb7882df3ac23","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.1.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC6NX4Jk29eSjIT90Pp14rvYD0Xbt+GdxQspsV47rATIwIgZhJOXO54uYtaqcthWheRSlSlpuk/IJqZ++Ty01mbYw0="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.1.0.tgz_1517317758744_0.5711459422018379"},"directories":{}},"1.1.1":{"name":"nextein","version":"1.1.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.0","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.3.1","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.1.0","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.1.8","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^4.0.1","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.1","babel-jest":"22.1.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"22.1.4","next":"4.2.3","react-dom":"16.2.0","react":"16.2.0","react-test-renderer":"16.2.0","standard":"10.0.3","taskr":"1.1.0","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"f4d8ee0d332e590d3448758e2ad7c8a7a4d5f4d1","_id":"nextein@1.1.1","_npmVersion":"5.6.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-b4fITmbkdLZnEbRco7DNi40kA+RvYxp/OBV7/R9JMj3NzcmpLcxG78FKpQWaQi9WIXv7t4RvjIdfPhvkPaozXQ==","shasum":"134a83ba98a8d7f236d07c60a62ffaebd0df9928","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.1.1.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDdhKBRp5n435w0R0SjD6+MxYZo1vIkodgTQ2n3qZjvLAiEAhnWdGYY2lmlv1yme8K3k96t1/2niZxLZir4pTJKRUec="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.1.1.tgz_1517606582564_0.6201471106614918"},"directories":{}},"1.1.2":{"name":"nextein","version":"1.1.2","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.0","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.3.1","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.1.0","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.1.8","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^4.0.1","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.1","babel-jest":"22.1.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"22.1.4","next":"4.2.3","react-dom":"16.2.0","react":"16.2.0","react-test-renderer":"16.2.0","standard":"10.0.3","taskr":"1.1.0","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"c554c3cd3a32baecab982592e4f2c7cf98d34621","_id":"nextein@1.1.2","_npmVersion":"5.6.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-f0gxu0lWByWqvNWnXOOffF1UwlgpibxyoMoY8csLAoRpyjLNA3BW0OUfPuKScd/GPGNeUZ9M8Yw0gZgYp8nSSA==","shasum":"0f65d0747c626fc9016c3495d175a14584c427ad","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.1.2.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGgOOFY4ojZcb3rvsbZNtsborhTN+7NH5zlam/ngqUNHAiEAzXrJjs5hLCqBI6dWUDQBmDNV0He7P7hAbNUTBxWlL5Y="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.1.2.tgz_1517688995053_0.5876703967805952"},"directories":{}},"1.2.0":{"name":"nextein","version":"1.2.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.0","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.3.1","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.1.0","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.1.8","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^4.0.1 || ^5.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.1","babel-jest":"22.1.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"22.1.4","next":"5.0.0","react-dom":"16.2.0","react":"16.2.0","react-test-renderer":"16.2.0","standard":"10.0.3","taskr":"1.1.0","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"9f10cfe71502c12f1566636a00628304c7550b2e","_id":"nextein@1.2.0","_npmVersion":"5.6.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-csPXe0AyN31iS1Y8TZ+2GUFjMarzk9sRL90/fjAt+xWw227vSNs3H2QzmARalgsjxG9TWNanKga4+Q5txfA+kA==","shasum":"72007e85d3abafb4ba52e59c18c7c09e1a750019","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.2.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICIM6KDa8VzL+a0dWBfICtoV0lsKxtm5tuvX9GQyqlunAiEA5apyfgsSV9TocOaKyk59RKm69DIo0P8T7G3jv91QJn0="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein-1.2.0.tgz_1517870913019_0.046896693063899875"},"directories":{}},"1.2.1":{"name":"nextein","version":"1.2.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.2","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.1.0","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.0","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^4.0.1 || ^5.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.1","babel-jest":"22.2.2","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"22.1.4","next":"5.0.0","react-dom":"16.2.0","react":"16.2.0","react-test-renderer":"16.2.0","standard":"10.0.3","taskr":"1.1.0","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"605ec239ee61a5880c878fa930bd0f440efe7520","_id":"nextein@1.2.1","_npmVersion":"5.6.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-94CJiVSi4UOm22yo4Df6wQF0Wi9PCV3WDOdfsRvSnouW2t29tBmUCHvtWlyCTuQzGbTO17AengKT4WaAJKr93Q==","shasum":"84bfd458ab092927da77f90ef28b450efd3d9d0e","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.2.1.tgz","fileCount":19,"unpackedSize":46134,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDEXxnec8vq+q+miDYMasM2mnostuAxPiCaXuED49h3IwIgAa69O4PjoWdTtKbc6ZDbRGwezT/oAMDshXWRxfQRtho="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_1.2.1_1518981384457_0.7241292152919943"},"_hasShrinkwrap":false},"1.2.2":{"name":"nextein","version":"1.2.2","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.2","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.1.0","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.2","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^4.0.1 || ^5.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.2","babel-jest":"22.4.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"22.1.4","next":"5.0.0","react-dom":"16.2.0","react":"16.2.0","react-test-renderer":"16.2.0","standard":"11.0.0","taskr":"1.1.0","taskr-standard":"1.0.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"a4162641a70c55f1ceb46589889ba3967e39e036","_id":"nextein@1.2.2","_npmVersion":"5.6.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-RHiTWEFYhVWg4WwbAwpAoD4dNScRsBaqRQNGDoocTyEOaGepeGuqlsNsWa5VMA1EOW3/aP+MFxcIbRdr1wA0ig==","shasum":"b4aee2d4db17eda8ae39ae0c4153f4420dc089c9","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.2.2.tgz","fileCount":19,"unpackedSize":46483,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCC/17MGCURgIK4+JZWOFrygd7OyNrqWO/wEJtL7bnppwIhAOoiYj0wjaX2WRP6yjihoeBNjdERtDLz3NA/MWwo4XfU"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_1.2.2_1520174203289_0.6611040732777687"},"_hasShrinkwrap":false},"1.2.3":{"name":"nextein","version":"1.2.3","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.3","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.0","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.4","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^4.0.1 || ^5.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.3","babel-jest":"23.0.0-alpha.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"22.1.4","next":"^5.1.0","react":"16.3.2","react-dom":"16.3.2","react-test-renderer":"16.3.2","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"0350b4bae77ed7611e88e2e8d4884beae982c0b9","_id":"nextein@1.2.3","_npmVersion":"5.7.1","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-pwb62rluSs+BQ8v8CnSpj2RxEZNXf7aAK+oRhROY6bYhHyEzl1M5qR0ypG0OqNOT0EABnqLHfa5LmTeBUDwDNg==","shasum":"741a55ffc63219cd35242ca58fb25783ed5a5c6f","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.2.3.tgz","fileCount":19,"unpackedSize":46200,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa1Ut4CRA9TVsSAnZWagAAKyUP/1SNsBalnavWHh9ML9iS\nO+SkfFBmwQxyd8MXWM2n4NrdxQQxYw/LxKFOT9Em/OSsZD09Szt4hYlAPHK0\n7ZFZSIDGVEdfgIbJAEKVA/OIVr8rsla5N9QStVaI8bl5lAdqA+FYQeT8cyhF\nB6C5jzYSmQkbzL9N2XFQUpue0GeiTRFzTMEmVPBcWMd91ntvRiZG6XZCwJgd\nFJoV0AfvDLBkzJuSOrBFNwuxS7cEHkrXufCjPa7PSR7pJyr5iWD/7aN4NGwh\ncx5/A0IJjGzI7XSJ83L7x2WGJZA72SGe9G+vAbLXo/t1ods+Wg4fUg9KLm+P\nRJQ2HN6CzFWmHiwkkPh5M3D+KPRd/+GvoaMk6QPA2gnPr8arRVccp6skHqvs\n2zsYuP7UVguumObumNn1WgfcPx8V9R2bbdy6oI6uldvsZtcz2bv/OMjCkyvQ\nKPyzfqtH9oY5YRA0AQAGINIUc0YWF34uYuRms1ts/GbKQDJcKfYreVMJ7NYW\nOgSRsOwBkEj1O1YKMMV2GP3G2/bRFZRhuSGWTcllJuat7Yie8mHSKlhugHAw\nwXJ8UINsL5kgQ6J//tXHqNqF3t487XM+y4LGEKR046tIr1BwXb4Pjod8X2rj\nBDW4tdtLr1YTgdlIGlNZzjuKJdYWdNydO9DoCIA2QVKkmoy2xkv2wVDZN5am\nVpqc\r\n=+ur5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICIxGFs3D/8fkTDx0SS/jyVEP2AuFacvD9TNAaCQ3cIMAiEAz6uz1z6Z+SKISqku9XV2ZJQ1RmfzX3hrpoeYw0zPohA="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_1.2.3_1523927927264_0.9617287414021913"},"_hasShrinkwrap":false},"1.2.4-beta":{"name":"nextein","version":"1.2.4-beta","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.3","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.5","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^4.0.1 || ^5.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.3","babel-jest":"23.0.0-alpha.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"22.1.4","next":"^5.1.0","react":"16.3.2","react-dom":"16.3.2","react-test-renderer":"16.3.2","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n        const nexteinConfig = require('nextein/config').default\n\n        module.exports = nexteinConfig({\n\n        })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n\n        import React from 'react'\n\n        import withPosts from 'nextein/posts'\n        import { Content } from 'nextein/post'\n\n        export default withPosts( ({ posts }) => {\n            return (\n                <section>\n                {\n                    posts.map(post => <Content {...post} />)\n                }\n                </section>\n\n            )\n        })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\"\n        }\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\",\n            \"export\": \"nextein build && nextein export\"\n        }\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const categoryAPosts = posts\n        .filter(inCategory('categoryA', { includeSubCategories: true }))\n    /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n    /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    posts.sort(sortByDate)\n    /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{String}` Markdown content to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    return (\n        <section>\n        {\n            homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n        }\n        </section>\n    )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n    return (\n        <Content {...post} \n            renderers={{\n                p: Paragraph \n            }}\n        />\n    ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n\n```\n\n\n### `Link`\n\n`next/link` will work out of the box. You can use `nextein/link` instead with the exact same parameters. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object.\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\n\nexport default withPosts( ({ posts }) => { \n    return (\n        <section>\n        {\n            posts.map( (post, idx) => {\n                return (\n                    <div>\n                        <h1>{post.data.title}</h1>\n                        <Content key={idx} {...post} excerpt/>\n                        <Link {...post}><a>Read More...</a></Link>\n                    </div>\n                    )\n            })    \n        }\n        </section>\n    )\n} )\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is markdown content of the post\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `nexteinConfig`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst nexteinConfig = require('nextein/config').default\n\nmodule.exports = nexteinConfig({\n    // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","gitHead":"976f5931057b03089fadc25d9c75ecf2d3f5349e","_id":"nextein@1.2.4-beta","_npmVersion":"5.7.1","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-xnvCR/W+yWFmAoNJFPkJITKGabxdlp0gQkRZfaLu5iEw+jB9dwOAcdmJIewWDSDBMZGYqnBgAUcAYPh2A2+X6g==","shasum":"c959bfee0f716d5aa565d2272825c30157a2c01c","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.2.4-beta.tgz","fileCount":22,"unpackedSize":47313,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa4/J8CRA9TVsSAnZWagAAJS8P/2U2m75T4tEezNC5Z4ji\nGM8tZOAkI3DRY6qOCO16X3yjFjzZ98irVSCzu3ADsSRkWbUQEgCUNT6u2Mm6\nfBxi/CvGzBpjDl1u7tw6fywwKCls1wb1F3qck2kYIMO37y/zN5bipspA3Mbk\ngR3rXF9Lh9//1rkwois3dSw/XNH3nUZgwSNbJHScqetKVjk9DfMJ5hbIZH1Y\nw4d4FeTb9f/wP8QkmXypdixKgJDlhJmZYImoD5QvrIWIICML6Mavxo/dJjgb\nZERHnUlwdS8rqRsTCNmC+lhgkkZ04JyD6yMdTDYh/RRt7cEG9ZC9jcItQSkE\nAEHyHn6Nnr8Wa7huIdxGoMQ2+5RoLF12hgFQWxdOfLMvc3if1d15P7j2z/FF\nFlZltSjInwcT1EBUVo351RUVs29cN+gZNAID6hTnMh77bJHBcfLssspu1oWM\nExGcA4v2zmyZ138ixshcss/SZ0T/+kokQCwO7id97NNAEdTVqiVvIfFAbTbW\nmMJVqzcFUBoCakPCcXjDGdWaBTYuiZraRS6so4t24UlTOeVo+ZJ7bNabIFYE\n6iT/Hzt/tNcoRIBOKHCbOItzbuHUX46+WVzmUj3qf9yYZdAYvO4up67rhmpp\nQATI7YWeY9Wn3VlDdNTGlcwMLUQebLmYvLgWZxCAx0KBVoVWFpd/l20Jl4tb\nM0UW\r\n=DL+1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD+ek49D4PwVkACp9y4yYEoOJ9j74F+wKtpNKplAziDZQIhAME7D2PVLnVN9J/UAV78juS7qIkJ8Fh+tlgZVouVqnwD"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_1.2.4-beta_1524888188079_0.11277307408610016"},"_hasShrinkwrap":false},"1.2.4-beta.1":{"name":"nextein","version":"1.2.4-beta.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.3","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.5","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^4.0.1 || ^5.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.3","babel-jest":"23.0.0-alpha.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"22.1.4","next":"^5.1.0","react":"16.3.2","react-dom":"16.3.2","react-test-renderer":"16.3.2","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n        const nexteinConfig = require('nextein/config').default\n\n        module.exports = nexteinConfig({\n\n        })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n\n        import React from 'react'\n\n        import withPosts from 'nextein/posts'\n        import { Content } from 'nextein/post'\n\n        export default withPosts( ({ posts }) => {\n            return (\n                <section>\n                {\n                    posts.map(post => <Content {...post} />)\n                }\n                </section>\n\n            )\n        })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\"\n        }\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\",\n            \"export\": \"nextein build && nextein export\"\n        }\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const categoryAPosts = posts\n        .filter(inCategory('categoryA', { includeSubCategories: true }))\n    /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n    /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    posts.sort(sortByDate)\n    /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{String}` Markdown content to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    return (\n        <section>\n        {\n            homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n        }\n        </section>\n    )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n    return (\n        <Content {...post} \n            renderers={{\n                p: Paragraph \n            }}\n        />\n    ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n\n```\n\n\n### `Link`\n\n`next/link` will work out of the box. You can use `nextein/link` instead with the exact same parameters. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object.\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\n\nexport default withPosts( ({ posts }) => { \n    return (\n        <section>\n        {\n            posts.map( (post, idx) => {\n                return (\n                    <div>\n                        <h1>{post.data.title}</h1>\n                        <Content key={idx} {...post} excerpt/>\n                        <Link {...post}><a>Read More...</a></Link>\n                    </div>\n                    )\n            })    \n        }\n        </section>\n    )\n} )\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is markdown content of the post\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `nexteinConfig`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst nexteinConfig = require('nextein/config').default\n\nmodule.exports = nexteinConfig({\n    // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","gitHead":"19348c12e6c626f5da757363bf197e0426efdcda","_id":"nextein@1.2.4-beta.1","_npmVersion":"5.7.1","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-nk5VpsEyU1YyZCUkMVZsIT5JIxr6kv3RznVRFKp04Pg2Sx0IXRc976SDOmK4zrJf4/Ec1JWIr0HjvFYXueZwZw==","shasum":"9f1faa8662c3322eafd5d495c37876adb7c09e96","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.2.4-beta.1.tgz","fileCount":20,"unpackedSize":46804,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa5NeCCRA9TVsSAnZWagAA9SwP+wcLGFQdvs9YdhGd+tf3\nzCAm8e++hIB65AIIsyrFibbwPeTqFy6hElHafwV8In1A7ftpkMGYK+gIdw1G\n52V5nmhH79BmI4/BkQ4YduKfysj5ZCiK4T2USvuIKJFx2MgTaZ+OIsNzvcrA\nF7HRqAlbCWC69pF6CtD9HV36imBTN7g3hF707BDVqwuyAplPEE7Rxv65Fjca\nkNRHSlR7/kr9B4B7XA+GBJYSmhvyPmrO6KVycTETqIOvfFY7jCBr5umleiBf\nM/dz4oYFa0p+4W813EXFALaRVOy4YSRa8ok801b/c8dXqMsLBy8D+lFKbVr6\na1Qqb4WTMyJKMeh944ObUEhVnGYUl5jLFOcDVZAJxppruL1ss0wTkZ8FdzQ+\nGjyUicuOYxwhVXqCztp+CDe5P4oN1jnrr/0+x7zMbHv8T7qqWNRZwDesv4tT\nM+HBfS64CJTQsmaoyq7tYnpIl/4q0Fka2lXF08065K/2OQKo19jBu/TENXKU\nHMcbFAf/RE11OcZFa92JWnLwMAGzlwzhF9InfyQQjYlwL8nCk5P9vpt4QD4K\nDunY5meWLkuUKx5tR3ceMWqmhAFRg5kA1PHO6NZFLoT0ozI/p2Cy6jY/3Nxu\nHOoSi1PmpAks5orcrhQuUmP7ZgOPgvVb+2S5kxO8VsRs37ybBCnFHKTMEYIv\nGdo7\r\n=q3eX\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDi9odpjp0Bllh0MSRWkD/Vb/OwlkLbRAKiJyIkefahdgIhAPITujEE/ul4GJn6gtskEQGNufFjizNEMcLQXyWRhTzC"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_1.2.4-beta.1_1524946817276_0.08334926948366017"},"_hasShrinkwrap":false},"1.3.0-beta.1":{"name":"nextein","version":"1.3.0-beta.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.3","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-stringify":"^3.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.5","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^4.0.1 || ^5.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.3","babel-jest":"23.0.0-alpha.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","hastscript":"3.1.0","jest":"22.1.4","next":"^5.1.0","react":"16.3.2","react-dom":"16.3.2","react-test-renderer":"16.3.2","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n        const nexteinConfig = require('nextein/config').default\n\n        module.exports = nexteinConfig({\n\n        })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n\n        import React from 'react'\n\n        import withPosts from 'nextein/posts'\n        import { Content } from 'nextein/post'\n\n        export default withPosts( ({ posts }) => {\n            return (\n                <section>\n                {\n                    posts.map(post => <Content {...post} />)\n                }\n                </section>\n\n            )\n        })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\"\n        }\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\",\n            \"export\": \"nextein build && nextein export\"\n        }\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const categoryAPosts = posts\n        .filter(inCategory('categoryA', { includeSubCategories: true }))\n    /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n    /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    posts.sort(sortByDate)\n    /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{String}` Markdown content to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    return (\n        <section>\n        {\n            homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n        }\n        </section>\n    )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n    return (\n        <Content {...post} \n            renderers={{\n                p: Paragraph \n            }}\n        />\n    ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n\n```\n\n\n### `Link`\n\n`next/link` will work out of the box. You can use `nextein/link` instead with the exact same parameters. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object.\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\n\nexport default withPosts( ({ posts }) => { \n    return (\n        <section>\n        {\n            posts.map( (post, idx) => {\n                return (\n                    <div>\n                        <h1>{post.data.title}</h1>\n                        <Content key={idx} {...post} excerpt/>\n                        <Link {...post}><a>Read More...</a></Link>\n                    </div>\n                    )\n            })    \n        }\n        </section>\n    )\n} )\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is markdown content of the post\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `nexteinConfig`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst nexteinConfig = require('nextein/config').default\n\nmodule.exports = nexteinConfig({\n    // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","gitHead":"a6cd5a65ffa347dbbea6cfa3046c944f7d09fce6","_id":"nextein@1.3.0-beta.1","_npmVersion":"5.7.1","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-J9uCtojHE30ug+2PetjE/Zzz3SgqY0U501C7jtKFu/own8m4R1fBOXlS1XlZ5KapTumJl2JxiPcEidQMyf+oPg==","shasum":"1966f2dc5d11b275f63e34ad4f39747b152caab8","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.3.0-beta.1.tgz","fileCount":21,"unpackedSize":47835,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa5UGUCRA9TVsSAnZWagAAd6UP/RGC7L2If51Ay08gv1dT\nIqvGthqxVssfq7f1DiNiiq2Zfm0Yw0oYPa+oqR60eq+ZaaV+HzUYeCsRWHDl\nxtU/BQ7k2sP3AVr8u19YIGjKio71a+8+QubY0POFNWj5hhDl514k2ZSpQYOZ\nUXjXO+19M2DTvpcqomk6M0OEPPGnAeRJrmlISy7sK8eroNktHZp0ootoi0mH\n3M4BAGp4El4njd5brQgFKyTX+RzITeWAzAZ0OxU+s3p9Fkl0nvudCY23w74d\nRlJ76Kfn9xMQIr8kYVHCJIEILkJaBUdv7rj/HQB6PoiXnkJhLOFZbc4H9usO\nDHU4xBnnPbrKT5sFyn7XfmZk5CltwUrZfvuoN66P32J6/9gXV+FF7uzoDa3G\nJHDvrh72FfQhtcl2H9SZPXU/z0eEDpETmPuhO3d4Uq1M79mgifhx7zp1/vOF\nZl0HIWZSzMhUH9vS18Ha1Q+PlKoe2GZ6fsxkTosEMwzrqclHqbQhBQNES9jT\n4QKtIaJgmaXMhcykcCgjn9BVUEOWI89cZwRLbRaLp+lKwsyCKg/6kcXwJb1l\nBTWUbvLmUZUj7vdbStNX8eRhzQUCOSnT0ej2fzVnldczpe8AeOzKlLyxJj03\nDPyox2m80INf6vRcAqBVifnJpJ53VuesRXLAV3MrqbrZ69VatxPFDvFnYnI1\nEb+f\r\n=AHwb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCJmoKWxUnzOMtR6D6OyRFEotxkkYkailbHHyBZqPkWyQIhANUIzcMP4wk9IRAeTnrM8dKz5KAk8rcNdP7x1Yo4fTpn"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_1.3.0-beta.1_1524973971486_0.18535785602418775"},"_hasShrinkwrap":false},"1.3.0-beta.2":{"name":"nextein","version":"1.3.0-beta.2","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.3","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-stringify":"^3.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.5","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^4.0.1 || ^5.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.3","babel-jest":"23.0.0-alpha.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","hastscript":"3.1.0","jest":"22.1.4","next":"^5.1.0","react":"16.3.2","react-dom":"16.3.2","react-test-renderer":"16.3.2","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n        const nexteinConfig = require('nextein/config').default\n\n        module.exports = nexteinConfig({\n\n        })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n\n        import React from 'react'\n\n        import withPosts from 'nextein/posts'\n        import { Content } from 'nextein/post'\n\n        export default withPosts( ({ posts }) => {\n            return (\n                <section>\n                {\n                    posts.map(post => <Content {...post} />)\n                }\n                </section>\n\n            )\n        })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\"\n        }\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\",\n            \"export\": \"nextein build && nextein export\"\n        }\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const categoryAPosts = posts\n        .filter(inCategory('categoryA', { includeSubCategories: true }))\n    /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n    /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    posts.sort(sortByDate)\n    /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{String}` Markdown content to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    return (\n        <section>\n        {\n            homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n        }\n        </section>\n    )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n    return (\n        <Content {...post} \n            renderers={{\n                p: Paragraph \n            }}\n        />\n    ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n\n```\n\n\n### `Link`\n\n`next/link` will work out of the box. You can use `nextein/link` instead with the exact same parameters. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object.\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\n\nexport default withPosts( ({ posts }) => { \n    return (\n        <section>\n        {\n            posts.map( (post, idx) => {\n                return (\n                    <div>\n                        <h1>{post.data.title}</h1>\n                        <Content key={idx} {...post} excerpt/>\n                        <Link {...post}><a>Read More...</a></Link>\n                    </div>\n                    )\n            })    \n        }\n        </section>\n    )\n} )\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is markdown content of the post\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `nexteinConfig`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst nexteinConfig = require('nextein/config').default\n\nmodule.exports = nexteinConfig({\n    // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","gitHead":"a6cd5a65ffa347dbbea6cfa3046c944f7d09fce6","_id":"nextein@1.3.0-beta.2","_npmVersion":"5.7.1","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-EYQzBV3UVND1Ms9+HrLXDh3gkHbXvMRImA6NKSdXC65tYr72FirTTuje2jd1fJAOCNcWrlDKVfe8RiqEiOetig==","shasum":"ce229b6855623b3919f7de457e7691d9611f3e24","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.3.0-beta.2.tgz","fileCount":21,"unpackedSize":47882,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa5eycCRA9TVsSAnZWagAADGoP/0+NpIS4qnBvfwGu9OQQ\nloM4IRa6WweBnz1EJt4+Tt+Af5UnxFTmuqhsXyhO4PJOps+hkiOx738NEjYw\n5iJqWfFjWebVzlztfIdl6KCs5mUkI44P0f0OBlr9X7pnRHGn0UOOzCCrb6rO\nVV1I3fTXWKV2U0CA6YeQsKF+M1xZVRs3KOBNTdc1v+vUO6CY1cTHpSzuUyWB\nTtCoUPJMxBf0RAKEAGXeVFIKyFnENvBxu8xTBVpzEIRblCBFfjjanXhM4XWb\ndd3FbTe452Fv5pGSnn0DheaNLxsMV70FtpczgDukHHeXKuN/CJi/rg09CXP2\nvXsGsL/uo+G/r+/sEFKOfkKgS9Mbmbzb30wtmlMdLjm76hiRb23X4EqAaBKC\nS6+uFslhy+TACDtf/wzuukjH/5EOJdRTYlpT7q3nm/qrUS127lFjXqKJGlKu\nw5RsG1DWow+WBIaNnT8tDIoCmh6zt81NXVFHw3C1CyVqAuu7B8Jbd55TGU4M\n+n29xRTYN0uyOfi0ISshVrnhbWlfZ68VAxHXLYifH7u+ButTu8qJgHdrtbWl\nRL/YzqeCSl8eos7/KtjyP+2Bo9IRpv/vnAo1KBZHbtuZmWQgDrTFXROZ6E0K\nLtGrWiejmM9ranLPWw+gjgY5p/AA/KyuOjxBzLPiS2e28VYgndJOx8Wgd4bT\nBVyw\r\n=V1VR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICiHAtFLZCXcK25oGNgxugzlcAzwrEc1BOA/oHvC99bnAiEA621YGsHCsVdVY2fHtyAshMgD5QxColYBMDYZ9TRTZ7w="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_1.3.0-beta.2_1525017755550_0.7287567912842268"},"_hasShrinkwrap":false},"1.2.4":{"name":"nextein","version":"1.2.4","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.3","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.5","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^5.0.0 || ^6.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.3","babel-jest":"23.0.0-alpha.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","jest":"22.1.4","next":"^6.0.0","react":"16.3.2","react-dom":"16.3.2","react-test-renderer":"16.3.2","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"e0f12a2e00eeda72712427c1a0889fd13c01ded3","_id":"nextein@1.2.4","_npmVersion":"5.7.1","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-V59sSXD3fX/txeLiyHE4qVfQpMgYpw02r5aJXayrvNFv3QGACB7M8ZI5OJIa7wCKbcekTJlUvFfuoYG4yhD4uA==","shasum":"6b550ebba50f2a9a4d4e2bcff536a8ff405aac99","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.2.4.tgz","fileCount":20,"unpackedSize":46919,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa6I10CRA9TVsSAnZWagAAUEkP/2DnHtnrUCHREd4fp78s\ndwoSheCwvOXdSuZcjQbTbovEUFmHySzOOANHvVTwDFHpkXLsWHPTXpev0mTo\nFdo3SGdOHi49vloPm0xIlNxE1boEurlP6McjcciVL6HP5V/AAxAg5/hX9/0P\nEHrFIWkfNp0vDgt2QuUKW3Cy8xitnp2VNV5o1ufkOrwVMBCsAF8bsYsGgMVw\n3iHfCqU6tGipxuaej1K0Ws1Ju+Bg/fYYOS4ZQwrpCZUeKQ728/flrt0Tk1ha\nG/080NPNmzCNN4KFYHK3fJi7q6dq5oMG1WYcQMLPc6pL4Fwf4iaH/7yX3iad\nTT0RuOP/NBojeGAG04f3tyLenp+sLZ3j3npe88qFIz7GHS83hKy2pe1V6pN2\nVXxPTb9B3TOt/9eYCZQ9djW7RdK0J/k6o6AEQ7teFfsEYXlU3qbrmWt6d8iI\nUcSKws4cNyUV2xMYUs5rjpjYbm+8abxiQxymgh/4GmLQ72kxyLhljpYtOoj7\no9v2WhArVSGS3gbghDXvcfaT4HL9hEYPv2VBgEvGwHUwRgL2ZiOOw6VI2Urh\n8pGZZbyIb8UmjFdTkdfCVR/STtd0ggFXbutQyVtk/nB3FKfvDm0vktJQlb5Y\nw4L8Co7KZ4AnLQXs2GyxEMqdmiRcMvNw1Uz02N/rQ9dsOoVI1z6m2YUj50KN\ntpOv\r\n=Pk2x\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCXcTWssKIiCcIKh5p07f5jxLmFPLm1qr5Aeyu1qftP0AIhAJldoxiqd3B5T65cx9jwSz6wfo1M1IduDv9bWK6qlAFf"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_1.2.4_1525190003057_0.7815035074634584"},"_hasShrinkwrap":false},"1.3.0-beta.3":{"name":"nextein","version":"1.3.0-beta.3","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.3","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-stringify":"^3.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.5","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^5.0.0 || ^6.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.3","babel-jest":"23.0.0-alpha.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","hastscript":"3.1.0","jest":"22.1.4","next":"^6.0.0","react":"16.3.2","react-dom":"16.3.2","react-test-renderer":"16.3.2","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n        const nexteinConfig = require('nextein/config').default\n\n        module.exports = nexteinConfig({\n\n        })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n\n        import React from 'react'\n\n        import withPosts from 'nextein/posts'\n        import { Content } from 'nextein/post'\n\n        export default withPosts( ({ posts }) => {\n            return (\n                <section>\n                {\n                    posts.map(post => <Content {...post} />)\n                }\n                </section>\n\n            )\n        })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\"\n        }\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\",\n            \"export\": \"nextein build && nextein export\"\n        }\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const categoryAPosts = posts\n        .filter(inCategory('categoryA', { includeSubCategories: true }))\n    /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n    /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    posts.sort(sortByDate)\n    /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{String}` Markdown content to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    return (\n        <section>\n        {\n            homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n        }\n        </section>\n    )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n    return (\n        <Content {...post} \n            renderers={{\n                p: Paragraph \n            }}\n        />\n    ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n\n```\n\n\n### `Link`\n\n`next/link` will work out of the box. You can use `nextein/link` instead with the exact same parameters. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object.\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\n\nexport default withPosts( ({ posts }) => { \n    return (\n        <section>\n        {\n            posts.map( (post, idx) => {\n                return (\n                    <div>\n                        <h1>{post.data.title}</h1>\n                        <Content key={idx} {...post} excerpt/>\n                        <Link {...post}><a>Read More...</a></Link>\n                    </div>\n                    )\n            })    \n        }\n        </section>\n    )\n} )\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is markdown content of the post\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `nexteinConfig`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst nexteinConfig = require('nextein/config').default\n\nmodule.exports = nexteinConfig({\n    // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","gitHead":"83a08157da6168eb2cc6cc41009c5c8f22d2c0e2","_id":"nextein@1.3.0-beta.3","_npmVersion":"5.7.1","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-3mdFHeOiZeeUabKtwnd21NA98oO09XsjdOBKkaQfrk6surkUY1gTU/X/ndvmwohLZMNM9wEqj6x0x8FHvHF21g==","shasum":"0f2e3966603613de5c70fc46e9842a2846140456","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.3.0-beta.3.tgz","fileCount":21,"unpackedSize":47548,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa7PPHCRA9TVsSAnZWagAAUvwP/2TugJEKon6STGc3/PTm\naYtn4zHHIUYhfkEAbUOWHwchGPUwL3btBaT0mU3riWd8eeWhJxhaY4C235dI\nkvha63A3AanUGg7y95mEwMeq07Ua5dV8hnBnqPwe/zMKgaMPLhFSdXOKjzZ5\n+ZOJLFGPQoeu7WoizRIiaD3qC2mPNXk30PjChArDKvl7Fctt4uI67RfjyIA2\nYFTS0g+oi6DIF9sENvrUnLSoOktWtdW56+luEqYj0xwbMj+PjtdnntZB2i8j\nSW94zlNAKzqSZhUTpIvkpyjSYVgGBO7pcU48lQX8ImLwSEaDhocx5RglTkI5\nHsF51//6GEIe9LCd9/SZh1wf+o/PJdhE3ufWUbOeKAAL2SO1WFHOJfrDoc+8\nK+0fSHQbjEvoz7gaJwxgDuQ67n+y/6DHXC3hGGIy9rCRymD3qfpfTebT2qlu\nksVlGXW2BmTIZ78nYDiACHPCLMPvbmSAlC+QGygBi1dGgYvvOq+uyDsNKRwa\nhHdfefggN2fAqAAmS5rGzFIKSlzFF2Oz+VzCJ+gspYexn94V6jesB+YhEX1P\najDo/W94RQIRtILD5PmLMO+UGmpHSqWzdt8KP+OX6BX3IIRNGUaCFHYW1Bh2\nrimzTBl8jQCLlpKZtUo+lLTnU6V9nFcq1ec/TMgAl9zMNVD3mGl7/WcLrUhZ\nwjLt\r\n=ERtT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCGFywVoHdVEYGeURyhqnHVy7mHbZo9yZ+0/mGz+5rgyAIhAM4cZHlGvOhkCVnZqE53xfV26FVe+TN3/T0rbmHOHnll"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_1.3.0-beta.3_1525478342894_0.7531547686440803"},"_hasShrinkwrap":false},"1.3.0-beta.4":{"name":"nextein","version":"1.3.0-beta.4","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.3","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-stringify":"^3.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.5","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^5.0.0 || ^6.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.3","babel-jest":"23.0.0-alpha.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","hastscript":"3.1.0","jest":"22.1.4","next":"^6.0.0","react":"16.3.2","react-dom":"16.3.2","react-test-renderer":"16.3.2","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n        const nexteinConfig = require('nextein/config').default\n\n        module.exports = nexteinConfig({\n\n        })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n\n        import React from 'react'\n\n        import withPosts from 'nextein/posts'\n        import { Content } from 'nextein/post'\n\n        export default withPosts( ({ posts }) => {\n            return (\n                <section>\n                {\n                    posts.map(post => <Content {...post} />)\n                }\n                </section>\n\n            )\n        })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\"\n        }\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\",\n            \"export\": \"nextein build && nextein export\"\n        }\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const categoryAPosts = posts\n        .filter(inCategory('categoryA', { includeSubCategories: true }))\n    /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n    /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    posts.sort(sortByDate)\n    /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{String}` Markdown content to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    return (\n        <section>\n        {\n            homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n        }\n        </section>\n    )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n    return (\n        <Content {...post} \n            renderers={{\n                p: Paragraph \n            }}\n        />\n    ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n\n```\n\n\n### `Link`\n\n`next/link` will work out of the box. You can use `nextein/link` instead with the exact same parameters. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object.\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\n\nexport default withPosts( ({ posts }) => { \n    return (\n        <section>\n        {\n            posts.map( (post, idx) => {\n                return (\n                    <div>\n                        <h1>{post.data.title}</h1>\n                        <Content key={idx} {...post} excerpt/>\n                        <Link {...post}><a>Read More...</a></Link>\n                    </div>\n                    )\n            })    \n        }\n        </section>\n    )\n} )\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is markdown content of the post\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `nexteinConfig`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst nexteinConfig = require('nextein/config').default\n\nmodule.exports = nexteinConfig({\n    // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","gitHead":"0cf0350c6d03e20400c7ab05672d90a12af0a00b","_id":"nextein@1.3.0-beta.4","_npmVersion":"5.7.1","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-hcBt3/PpA2uDWfnXCQrav3KV/K2I+ltTRchQS3AMymKVCgAmQCGG3ZrAzJtIpiIoF3czTYdxAldhmU9jIIYR6w==","shasum":"1ea56b3d9d42a6085a682bb32d43cca6bc36e728","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.3.0-beta.4.tgz","fileCount":21,"unpackedSize":47647,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa7PcpCRA9TVsSAnZWagAAfJMQAJclELOIga2O4FQ9jBOF\nnIeT1ASnjSct0WDlJ2guzW3+hXKjBm/1Ghe66q50ULgwEt4vT9Fq9j+pL/Kh\nv5kV+Ci96yVz0X5FD65hvyINkTty+Ag9BJR4v29x87SFWCC/7dFKPyLXj9Y9\ni5v6ayadBmTQd2cTrTOoZWOXuXNXn6qlaLX8sGjCJ0JXg5fqK0Fhu1am40oA\nAjeFEleKHojcO3Yb5Ddu/8SxZl7sv2NYsm1wcCg2F9l+Qr2XNyCAetmcjDfA\nVzGDN6q+pd2s5nGlbF8g6N3PxBz7FmmuBj3qYE7YXEGpXS4DoEwsD0Sv55pd\nKzXsVV2+VXtE0AVg1JN/vpdOV4cBpCPgGBzj+Wd1I3OGPTcyKqu5vsebp22M\nvSs6+XZHubxXe4qGXc8hFEwOprCwTOfksmf8W8JY8G6Tr9sNZNa9AEdHQiup\nscmvfB4lkAXl+8lVgfB6d2ojKYTkn1/3yCaS38bA8u3+OOKkEHdUND2byRxG\n7kcNylVfoI53ZN26W/XhOwNChi8GJnfomwWVZDYBWzRjLCWINwF8PoWHV7gz\nP0q4w/dsKekFFm8Zobbk1rXsauAVpAvkplrFqSckzLB2ORI5yanTWhdFctDr\nhHS2JOEyiEBVrXCZ/gTa2DOg0KaulSGlYWOCX25WrsRTSlWEpnvkf+CuUwWq\nDPAK\r\n=OeZt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHyZBaNL3y89S8pwbBgJsR8ZxbDoqPyQBskU6VLgxYBFAiEAy8rA5lpyRT2pfuTRaQzuBs1UNG2R71xyxM18Nq0tTjI="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_1.3.0-beta.4_1525479208073_0.05027054380205831"},"_hasShrinkwrap":false},"1.3.0-beta.5":{"name":"nextein","version":"1.3.0-beta.5","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.3","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-stringify":"^3.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.5","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^5.0.0 || ^6.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.3","babel-jest":"23.0.0-alpha.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","hastscript":"3.1.0","jest":"22.1.4","next":"^6.0.0","react":"16.3.2","react-dom":"16.3.2","react-test-renderer":"16.3.2","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n        const nexteinConfig = require('nextein/config').default\n\n        module.exports = nexteinConfig({\n\n        })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n\n        import React from 'react'\n\n        import withPosts from 'nextein/posts'\n        import { Content } from 'nextein/post'\n\n        export default withPosts( ({ posts }) => {\n            return (\n                <section>\n                {\n                    posts.map(post => <Content {...post} />)\n                }\n                </section>\n\n            )\n        })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\"\n        }\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\",\n            \"export\": \"nextein build && nextein export\"\n        }\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const categoryAPosts = posts\n        .filter(inCategory('categoryA', { includeSubCategories: true }))\n    /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n    /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    posts.sort(sortByDate)\n    /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{String}` Markdown content to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    return (\n        <section>\n        {\n            homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n        }\n        </section>\n    )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n    return (\n        <Content {...post} \n            renderers={{\n                p: Paragraph \n            }}\n        />\n    ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n\n```\n\n\n### `Link`\n\n`next/link` will work out of the box. You can use `nextein/link` instead with the exact same parameters. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object.\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\n\nexport default withPosts( ({ posts }) => { \n    return (\n        <section>\n        {\n            posts.map( (post, idx) => {\n                return (\n                    <div>\n                        <h1>{post.data.title}</h1>\n                        <Content key={idx} {...post} excerpt/>\n                        <Link {...post}><a>Read More...</a></Link>\n                    </div>\n                    )\n            })    \n        }\n        </section>\n    )\n} )\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is markdown content of the post\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `nexteinConfig`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst nexteinConfig = require('nextein/config').default\n\nmodule.exports = nexteinConfig({\n    // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","gitHead":"1e6dc0aad3659853a01871780f85cca30d188a52","_id":"nextein@1.3.0-beta.5","_npmVersion":"6.0.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-PbVTuKMzkF8kJPZPUdt+wu6uuvFqw/ps5vikIA7IwEMaoMz/lT5VWRLAVmyHeOt6gLZrsW+/Fvf/rENPZ9MPcg==","shasum":"aa297862d8b3a8173ddb4b4a00e921f175cddd61","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.3.0-beta.5.tgz","fileCount":22,"unpackedSize":52163,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa97/fCRA9TVsSAnZWagAA+NYP/1uPDZqvey1zBQt6ZPkr\ndI4LwsoP4OVQkG6MoDSQ0JUZkwsxltefDtPoFW/I7l7GM3xU62jVZQJ46GIb\nSN9WJVBbkEViWcn+Qw4YcRENn24SGW3c+d8EVgEYjXUhb5s1xNvebAOfxcB+\nADukz7VsnDiDHs1/rW7HaCzM9m0dbbxbu05625cZjLS9xi1Jmv6Gfsrv++wk\nyzsfKGM4J6WGF9PSsE6/BpoSRp3zMVJmyspS44o07O84YZsD4CgjoN42PXv5\nnxooJMnZcNdA7ohJsn4L44AzIE6kSDLmJM8ei17mBERSPg6FENfBuA29kfZF\nnSaee5BBE5Zewb17Rm4nsR+4LAya8viv2HiXo2K46PxIrKK5UdgQA66bLWJZ\nO1vzE0MdOXUGb6DOL4OV3b6mF6CBxMfCcKllvyp1h4LMcBOaEhahZdKshaLo\ngeP5bO+rWRUiK52AD9E1Qn7kZfnJiup9H5n5HpER28Lgrdtb3F7AZ7aYQerQ\nvmCKxQzqBBeWVSpyAfU5SUUfDFU81DGpuSK3MiTvpU7GbEuXMdVMJM2QB2wT\n0nb74DK+7hoSokvLTrMi+gqcRcxptYfuLLvzG2pzYUhwnZKLOmRTjLs0mzuW\ngD41Rw+4l6nmBxYLJjF7qXivaVewbPxBjiWihor4N8KiLNL7Az5cApElzG6k\nkB1P\r\n=wKrg\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGEoSWnpFL3SISs6Hi7KKMY5IuxwIfQD78stdO5GLnR+AiEApQqCtKTa/80aXgzBTELThXV498h6ytcUkZ+yeOxnJNo="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_1.3.0-beta.5_1526185950845_0.36053888183667104"},"_hasShrinkwrap":false},"1.3.0-beta.6":{"name":"nextein","version":"1.3.0-beta.6","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.3","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-stringify":"^3.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.5","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^5.0.0 || ^6.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.3","babel-jest":"23.0.0-alpha.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","hastscript":"3.1.0","jest":"22.1.4","next":"^6.0.0","react":"16.3.2","react-dom":"16.3.2","react-test-renderer":"16.3.2","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n        const nexteinConfig = require('nextein/config').default\n\n        module.exports = nexteinConfig({\n\n        })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n\n        import React from 'react'\n\n        import withPosts from 'nextein/posts'\n        import { Content } from 'nextein/post'\n\n        export default withPosts( ({ posts }) => {\n            return (\n                <section>\n                {\n                    posts.map(post => <Content {...post} />)\n                }\n                </section>\n\n            )\n        })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\"\n        }\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\",\n            \"export\": \"nextein build && nextein export\"\n        }\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const categoryAPosts = posts\n        .filter(inCategory('categoryA', { includeSubCategories: true }))\n    /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n    /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    posts.sort(sortByDate)\n    /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{String}` Markdown content to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    return (\n        <section>\n        {\n            homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n        }\n        </section>\n    )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n    return (\n        <Content {...post} \n            renderers={{\n                p: Paragraph \n            }}\n        />\n    ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n\n```\n\n\n### `Link`\n\n`next/link` will work out of the box. You can use `nextein/link` instead with the exact same parameters. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object.\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\n\nexport default withPosts( ({ posts }) => { \n    return (\n        <section>\n        {\n            posts.map( (post, idx) => {\n                return (\n                    <div>\n                        <h1>{post.data.title}</h1>\n                        <Content key={idx} {...post} excerpt/>\n                        <Link {...post}><a>Read More...</a></Link>\n                    </div>\n                    )\n            })    \n        }\n        </section>\n    )\n} )\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is markdown content of the post\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `nexteinConfig`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst nexteinConfig = require('nextein/config').default\n\nmodule.exports = nexteinConfig({\n    // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","gitHead":"5949511d2c0c0fdf4af48d6cc40d3761d2eb5ccf","_id":"nextein@1.3.0-beta.6","_npmVersion":"6.0.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-X34I1Z3mWcng1v9iKZC6O0E5j+1p1ujC8ErZuFwr5Qwj/hzh3YdDHpZRE8NcRE0WEl3W9HAGPbnV/4P5QtbCpg==","shasum":"06a615af61b90e7e57690d3823db600b7761659d","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.3.0-beta.6.tgz","fileCount":22,"unpackedSize":52163,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa+QD5CRA9TVsSAnZWagAA1W8P/2eT4vgGI6IYuJY+wWlK\n74ZcjHBjlY+ai0dWPsBbz6OMMvzvXzBpoFW+wOkSBief/ZsC7PkTNYKnXdqU\n2IkF5wVYdXg1vYYy+7NEN2JRsfr2g5V6xmIya334egsFM86ou+6gFVOpD3R6\ndCIdzcHUkJ3oEzgM92dToOxwzsRHu2XRXXBsO6HZtW/Ea4W/DhIn9AOBWkyL\nlFkXlCvflx1u3+wX/LDQSKjzoSETmHpHcNz9G2nUiH6KCOVVkKxAX4HAnQt/\n0LVsI/MJp0OohZeVtWjlng4CU3MULrERjJuEIgq7t9RL8I6PyWMfvZU48Pfi\nHJA1bfdJNFCR+QEfclJiqgFTGGHPxk9Y6As6OMPmfptn6Au0VIes4exbXn0z\ndqgjwPBPhq4LD+pycyTzhvldz6a1mguOcKdCZyE3hXa8CZq2GfJRy5iHvttU\nDlQATL4vGc86hwBkMdB0ruvSiy8/Pk72pmcRvOOSm2B3dQKopXjgkk4g/YAc\nbcVq5WNtJMl920853HzEZ1RJO98cUSft84PADL26fePnncUm74tYWNCJvDR+\nmf4/Scxddefthy+v3kzhh2By5X2rWE5718jcXNwtuHlJj7XZegyfM15dRzrT\nR8Pr5Gi36G5nEy5q6si6KaYx1QW1IJPzDA3rm2Dk4PnE/NzHF7Y+SlEY9hGi\nkVER\r\n=ANAy\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBKrxI958RZeitqeq2xHVKWFx1RUvJhi8UIUzGxLMp0kAiEAxYEQZpweTZ9CnlwaiZHQLV2lqi4124z21ddwU4nxnMA="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_1.3.0-beta.6_1526268153345_0.7362061354915319"},"_hasShrinkwrap":false},"1.3.0-beta.7":{"name":"nextein","version":"1.3.0-beta.7","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.3","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-stringify":"^3.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.5","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^5.0.0 || ^6.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.3","babel-jest":"23.0.0-alpha.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","hastscript":"3.1.0","jest":"22.1.4","next":"^6.0.2","react":"16.3.2","react-dom":"16.3.2","react-test-renderer":"16.3.2","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n        const nexteinConfig = require('nextein/config').default\n\n        module.exports = nexteinConfig({\n\n        })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n\n        import React from 'react'\n\n        import withPosts from 'nextein/posts'\n        import { Content } from 'nextein/post'\n\n        export default withPosts( ({ posts }) => {\n            return (\n                <section>\n                {\n                    posts.map(post => <Content {...post} />)\n                }\n                </section>\n\n            )\n        })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\"\n        }\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    {\n        \"scripts\": {\n            \"dev\": \"nextein\",\n            \"export\": \"nextein build && nextein export\"\n        }\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const categoryAPosts = posts\n        .filter(inCategory('categoryA', { includeSubCategories: true }))\n    /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n    /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    posts.sort(sortByDate)\n    /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n    const homePosts = posts.filter(inCategory('home'))\n    return (\n        <section>\n        {\n            homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n        }\n        </section>\n    )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n    return (\n        <Content {...post} \n            renderers={{\n                p: Paragraph \n            }}\n        />\n    ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n\n```\n\n\n### `Link`\n\n`next/link` will work out of the box. You can use `nextein/link` instead with the exact same parameters. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object.\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\n\nexport default withPosts( ({ posts }) => { \n    return (\n        <section>\n        {\n            posts.map( (post, idx) => {\n                return (\n                    <div>\n                        <h1>{post.data.title}</h1>\n                        <Content key={idx} {...post} excerpt/>\n                        <Link {...post}><a>Read More...</a></Link>\n                    </div>\n                    )\n            })    \n        }\n        </section>\n    )\n} )\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `nexteinConfig`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst nexteinConfig = require('nextein/config').default\n\nmodule.exports = nexteinConfig({\n    // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","gitHead":"076f4427ab72bca87265cd3db1b67b0ee6eab5d4","_id":"nextein@1.3.0-beta.7","_npmVersion":"6.0.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-KCmqOr14NhZO6j2GNlJO24NAAAKlxtmZxy1u53bOhoCLuGgkk51VHvmx6JvNq6kTtVWUoPO9WghGEGkNBr05tg==","shasum":"947067199795ec816571623df3d11d4763a1ae21","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.3.0-beta.7.tgz","fileCount":22,"unpackedSize":53001,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa/PYnCRA9TVsSAnZWagAAhG4QAIv3KZ435n+EgjazkFtP\nDJCDCZuOkQ6Co8JhFXVTfTF5ffzgnx1Ytvrbkh8ReOaXn44tNGUG+aB6BFx4\nP4VyJDKYhgIjxVRygWEDb5/N+FBEgqP3+xw4Ux656aRTaSO7E6W0hnMvKXDY\nuq4OvmV36y4/dmULv9XA9HWgEqblYEbLDNU20cfAlY60v8OpLNUAMYX+IR81\nsBi/D8LXAOO3/eCMyQ0+KrTx8vC5kgwkQfGgY2BNf/N9JG2wv+Ip431R70W+\nGcy5/FKNwiDw8A8LwabC1BZTv8xC73QznRFSa9Sbfp0l1O/cwSxYAruJ91iS\nhMS38eDMuGOhVJ3ZqpneOn/znpilAQGPDBgtQs8rDko2/3ExdYecfPzuealj\n8p+6oAsU7kmEdBlXBZJE4EgClT1M59Al84XLxhVUlZCvPwDE9UF2o+5KNPnI\n8sYLPd7NKPgilKdYbhp5ujQNsm2BghGUIMn/KlN4zB6vqcXxN2QJqja00KjZ\nZAL8Me1HwcyczCXsC20z4UKw/PZzVK8PQrqpUiRESd5u8aVbaYK6gT9Ou/tl\nHZJskYM9oivpckGq5jCKBZg1mNbzXRqwJ467MZ9Zb9jgM74W+kO/hQQaaZpH\nN4WfxOkHdxuhUTP9OxZWASMXORMnFi0lAV5qo519+iPWqaddlvdTOE+VMnIe\nU/F3\r\n=rLhF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFfeaCQH6GDKHfgELv633jZjuL8h7NmFbAy0OVaRAsPEAiEAzIICXLZy0F388yrzlfwEY0brPyHP3Gv1H9MZddEXBIg="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_1.3.0-beta.7_1526527526453_0.640677052402824"},"_hasShrinkwrap":false},"1.3.0-beta.8":{"name":"nextein","version":"1.3.0-beta.8","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.3","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-stringify":"^3.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.5","unfetch":"^3.0.0","unified":"6.1.6","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^5.0.0 || ^6.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.3","babel-jest":"23.0.0-alpha.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","hastscript":"3.1.0","jest":"22.1.4","next":"^6.0.2","react":"16.3.2","react-dom":"16.3.2","react-test-renderer":"16.3.2","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const nexteinConfig = require('nextein/config').default\n\n    module.exports = nexteinConfig({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `nexteinConfig`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst nexteinConfig = require('nextein/config').default\n\nmodule.exports = nexteinConfig({\n  // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","gitHead":"e8e90658bfb9293c90e6094b0b392ea91aad255b","_id":"nextein@1.3.0-beta.8","_npmVersion":"6.0.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-UZWdBS/Va8FI35eF0ol53ENaVL/36W6BXwHu8qkBMr2LHT9AV6Z6ooPomn3/1qDb8iw0e8j+rEhvKyOFszOfrQ==","shasum":"2e95e058db58bd70cca2c80a5f44d6018b9841e5","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.3.0-beta.8.tgz","fileCount":24,"unpackedSize":55381,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbAIZMCRA9TVsSAnZWagAAHHgP/1FJ4GjK0r5YDZAtFPLq\n5GQwaFgPaF0K8m7q3EhnXTS3rf7RUe79qUAdk4GmXau7+SGk++dFAv7VhCr9\nBn2VfDv5eMtbYiKcWeOBKVqfYQwI16ljzB5+sAQMzpslKfwgCgazyLRFwwTJ\nRYn1Iri3nvdHqkIcsOuky1TBKHAumQB6lP+KnkilSVA45L2Jl5Lmqkj8pLbP\n34ozWNgWR49KeQNXt/ybbndoPrHB9KlyfWcU2wqA9faWSL9uKsLnKnJaJpVu\nYTCNRfEwlNMo+tIdp5bn+mGIhSkV7DWMrFW9fj1euRwxenjzruDml1rKtebs\nTv44UsZTXRmdPT7R5YD8cmX5C1jTMIXtgFxfGjV8ImsKzeM6Y0z9G3rze3nO\nvtQKkz2GDCYjIQCZvAqFTab+VMO0vYhxeMMqgDEONUGio/PvMya7GUo0ma1P\nO2xHmRUyn1gUvLnYH/OSZNhYGqJKEuDypHSXUVTACAyiTDxF4sBDaIGccocF\n+0aAznFzMXNHRhiRt5KDTrx1ZfvOFch15VR/BRTImx0EsU4Sb5D4pmAZ+mxU\nCbg8ms0xh3DkCTRQA63EO2FTNnSDqJDsn0ey6sg9qztWp0PXC2BuZuxAUvIS\np/sfHfgcgj8ojGx7E9oyMB82CZTvyYQ3+5Pc8piJBaZLZcxO4gn7Mu6N83tj\nyZSa\r\n=z0XG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBwDM2JWmFFCzNIqaIrOmO2+NKObvcBiT2uQN05gydxmAiA6orW6V4sGlHqkaS+44gbPqTRSonf0uuwZjs+ws7ZRmg=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_1.3.0-beta.8_1526761035689_0.1732639667357947"},"_hasShrinkwrap":false},"1.3.0":{"name":"nextein","version":"1.3.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.3","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-stringify":"^3.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.5","unfetch":"^3.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^5.0.0 || ^6.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.3","babel-jest":"23.0.0-alpha.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","hastscript":"3.1.0","jest":"22.1.4","next":"^6.0.2","react":"16.3.2","react-dom":"16.3.2","react-test-renderer":"16.3.2","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"c38b16a0950f9233f0a916f2ad9d677acac76831","_id":"nextein@1.3.0","_npmVersion":"6.0.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-2mBJfoLaScgTmasfG/HblJ4e/ZYf/B4Fv/Lnt3AnD7Nn0mwoedC6mR3ZFrLyt8yxQZFOceMAElQ3DXUkh8GaMQ==","shasum":"e47f90c87869740f41278fb5f4dff076d790219a","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.3.0.tgz","fileCount":24,"unpackedSize":55374,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbA0GKCRA9TVsSAnZWagAAPK4P/1XxkAln7icKv+vVlwhO\n0v3g7zhBJmE4de4tuOJvtVe9mFptXEyWpOhK3nYgSjCkFRWmSChZAf/bvfet\nDX1GEJf3/CtRKRiliCqXH97wx29utnaV3WLkQn0ZK/PSDnxOmkfyGbbdv+H3\nfVrRol1n1hDOtRYZWLnxg3dYlqstiuSE4jWq+uYD2XZyZzR0fH0BzaBpMKEx\nMWbnhljlVRdEPP1lVOmN9r3exdt47h57D1y4Pspei4ps0Syw59v8HMCioX2D\nMFg/W2RZquGqgU24NmmGG6ZB8ppW8vaYIfzIuMJTmI3WSo1IDMDXBXNkTybN\n5SEXECPd6Vjhm8OQVoKNu0meJXWe5HPBoK1beHFNqkpHnAE00UDZF/ly0BKr\ndIOL1YcZw5T1n6Vca7iOMo2w9XyFLkN8+l57qAtrGvgS8Q0HGL8bK4z91M14\nk9ne+VvRRcdZp4n9ChhBL7X8JMZuGnFni2O7s4ABxZryajJXpFq0GWs+PWEY\nfLziKKjl6ILIEnOAyWinca7e+BUdgJEBbZHA2s/ji0sH4LbJ8DLxAHkMXlN9\n8I4NEYEgH/Yh3LiNg21rTStId5Ujx+ZdAdB596rdR2orf5IJlwmPSz1U6sQJ\nqWo0eWfEMoy5e87/6rzoXoNYsraaIXitb6Nj3kF9nwdQ6gGL4LPHk5/TRTL0\nMsp2\r\n=zXze\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE1GjA+xQKgLNJEtEbA7MFI1imDKFzRTVwaDphn+8wjHAiEA90/mD2LtaqVXKELe9rT3Rg+zaAi2/QBKcjaN/tbHnxU="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_1.3.0_1526940041136_0.09965514489672045"},"_hasShrinkwrap":false},"1.3.1":{"name":"nextein","version":"1.3.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.3","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-stringify":"^3.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.5","unfetch":"^3.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^5.0.0 || ^6.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.3","babel-jest":"23.0.0-alpha.0","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","hastscript":"3.1.0","jest":"22.1.4","next":"^6.0.2","react":"16.3.2","react-dom":"16.3.2","react-test-renderer":"16.3.2","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"275e8ad20f9b3b86a4943806eac73b4a03ab148d","_id":"nextein@1.3.1","_npmVersion":"6.0.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-Sa79u04PAeFSG96o++YTiTaF7aZvIm/B33TGEqx3D2g/hQnWqdWx53s6lo+LdnEPSSg3e7Hhozbk1U3QIU2OVg==","shasum":"3b3ea3ae61b6167afc7d84cb065e3cb1cc70b63d","tarball":"https://registry.npmjs.org/nextein/-/nextein-1.3.1.tgz","fileCount":24,"unpackedSize":55378,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbBH9hCRA9TVsSAnZWagAAJb4P+gLAdoESRfdfEY44+kwW\nFZLdEECJp+PVeJVwcg3MY5fCnRXNbjIEnb77KL/ny95ZM5zVReJyNQekQDz/\nRVlUI0p8IIKipeuvE4tw6nDP5s1uIvSUiDq7uXkUtXh+OVrFdTtjO/49giWG\nwu1oIOj61QrjjdRPG8PHGOwT/pFhmvcAMLpCopBoIro9X95gCKd0NJFme4Qe\nRw1+n+DXGLwnxph7kX/A9ygXsRknbLC+b6qUbz+Ppnf2nR9lQ1aqk27XsVD+\nSpbH9WEEx2OH6uEeIcmRZplyWJh+7De5XOcLCLR6mCgq4H67vDaYQ76F6SE2\nb9iQYc1Xkg+IYGmnpD8W1Mn+i4eQflfp2C5zN/pQnVKB2Yh74y6GkeafVJDC\nQA13AZqwuLdBO59I+MqzUNDOeWu5YxAPMRngUAradmSY72ycxtnR9UhcQg9i\nG2Jk+0V6U0N0j3PlmiqU9BHbizRGZBdYwHsztZlktV2dtn7yhAbyi+p5B/tt\n4fC0SU/dSlnOwpb561vmu7IBlmKQqlTOlCwlglHJEEa5ld4/8hdilDsMy5ha\nkyYzu5/QEsuVJmHv7BDKf0O7wdhZE02Fu9JdJsQDsfSeMMVjjR03tGOjI9DB\nw6sgDJRqGhjT67zHgn3hMs/Z2GTgN+LIzQsBmA+86edtBLtyTlZo2/7DflDt\ncWWE\r\n=HcY7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCOJ+W7EZ2PWxmS9BbGviv8XYQWXOVWJxthWgK8njLgCAIgLxvkX86iTcGG8zhzzFELDx+Zf4z6876/4kVZ9lC3pIQ="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_1.3.1_1527021407139_0.3725236919218642"},"_hasShrinkwrap":false},"2.0.0-beta.0":{"name":"nextein","version":"2.0.0-beta.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.3","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.3","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-stringify":"^3.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.5","unfetch":"^3.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^5.0.0 || ^6.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.3","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","hastscript":"3.1.0","jest":"22.1.4","next":"^6.0.2","react":"16.4.0","react-dom":"16.4.0","react-test-renderer":"16.4.0","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const nexteinConfig = require('nextein/config').default\n\n    module.exports = nexteinConfig({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `nexteinConfig`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst nexteinConfig = require('nextein/config').default\n\nmodule.exports = nexteinConfig({\n  // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","_id":"nextein@2.0.0-beta.0","_npmVersion":"6.1.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-JRkmzdKFj8DnXyNQ2usz7ofG4WRu16mslWSa8Gkk+a8RCZprU1iQv50anltGOUZcBZgr5JCrkgLb2d9M1pT1WQ==","shasum":"0073df9feedd2ca5d182f63208dd356de43d2e87","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.0.0-beta.0.tgz","fileCount":25,"unpackedSize":65485,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbMvQxCRA9TVsSAnZWagAAGMYP/0D6/FGSaZki0AkHbmlN\nT+9IOyu9dVI+z8Y1XgqKjijnbeR4BaSl26q3KaEK+7oQg55+RdzwSBCOUJPJ\nU2MfWubvn/BwitL6b+RKdXXllEi97kNUtldtck1qmZcZ+g7OlCoVEqSmRmuo\nLST15HtUXWERDZ0thtxv3wgAMZddcfdYvE2Z2sK6N3f+559CBuWNrqHAV1G6\nyj2cOiZabW9EUo1CTb85rwWb7OPoYgabg85pnhSCvzpC34lHGVURuTctK1QZ\ni0Pad6uRZO6/b4h5SdfCjpd3pvq37/EbF5LWHWsLyqbuuQdoQmQ0S4ZjTtwo\nGcYg9RVlbAFtbIpC2P9Hl8yuqhba74NSWM8bi/gVYbe/teYrz98FnGsQgKJM\nLQf5u9YD/5LhjaSfthjUyUMYas7WoCJbw3LyUtPeogGjA6E310og6EqRl0S6\nEUluGZFrLOXy1zsz68hSKW00BPRHwOBRWguf1FQDZul2Hfilph5OCmfsGAk6\ntsm6uTK0PaKuhb7lgbGqbK2vdLjohutBwd8z+r31sKvSnNXuhiA28VBDctWW\ngXPZK3qqTnSqAQ5qpakdJ+Ai05SUopVmh2DRcDdasVE5YFF65wU2whcMby5J\nuWvCnj6Mg/UWRZd83DaD6q1EWZYYU1s4AfruO0oiKVgSDIf+9i6vZWSUOqSz\nTv/O\r\n=TXZ5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDBck9qfETXCZWnPKvYS39/jYcuNHtActf2Of0FwsTVZAiEA90W7bAEsvaKhE3q9rEqJN87qufYvCaG9J6KON9gqWk4="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.0.0-beta.0_1530065969076_0.8941941495787058"},"_hasShrinkwrap":false},"2.0.0-beta.1":{"name":"nextein","version":"2.0.0-beta.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.3","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.3","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-stringify":"^3.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.5","unfetch":"^3.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^5.0.0 || ^6.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.3","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","hastscript":"3.1.0","jest":"22.1.4","next":"^6.0.2","react":"16.4.0","react-dom":"16.4.0","react-test-renderer":"16.4.0","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const nexteinConfig = require('nextein/config').default\n\n    module.exports = nexteinConfig({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `nexteinConfig`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst nexteinConfig = require('nextein/config').default\n\nmodule.exports = nexteinConfig({\n  // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","_id":"nextein@2.0.0-beta.1","_npmVersion":"6.1.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-ijAgiaps/2iQJiJSwhgWxJia/8GK9hZV7yE8sVlm+46lsGHBIxwd+kN/CPJVAc9SWhrLnJfpBHfPy+wyu0M9Pg==","shasum":"73512b7a37652f92079f930b594dec6ccf42a894","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.0.0-beta.1.tgz","fileCount":25,"unpackedSize":66349,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbOqrVCRA9TVsSAnZWagAA1NMQAIcK/YvqJdgZiVLYqXAm\nURuL0ol4iJ+dtn7/4b/+vMkuuUlnlkmfqIlrhS5PAA7voiJrAzVyxWR2yKqu\nFfeovmuL0/Ngx7obQVNTi/Osgz7DBCYKnTo4lkG8HYsypNGOZboke61Qwzy8\npte6pSICMQw3ZcXOxMsRr9nFzzVkv5pM1dTFFd9/ClTp62L0bYrxttlmIKmq\nS9D3YG9FRupyKksl8n1MyVdlL56XRdgO7cPnFYtrh38TUVVfMvxJlYWHq8N1\n37Um0GExuqvYiKrcvgHdXcw2VZJnm9G9y1MBxoZJa9Fw8Kh62yMOqkXWtP6q\nNDMP89+O5YDWcYuF94L/MdePqWTmKEhA7XuNCbf3NKeWEXpIsrnHCPTbUdHK\n9SBsT6z31yIvt1WreryKzzOH+cujxySJ8I/CPcYZcarp2J+WGrYT+Neyo9rn\nx+zvZFN+25pYmOYfyMY0pMgsVrrdQeWuX0zDDODJ3B0J1iXeQEtSwhBCY6LB\nJYGAWYE3hnc6ZMIfI1uyWL1ZTCdhzCobhky8rGJVmerhDFcvH9r+RXPggf1M\n/+J61E/usCsZlhniUnmhJ4wWM50rRI0OceQ60xWwJGuDu+fjTiD++fJt2DPE\ndfMSrCU6AlQArlZCWjbzFSuJbjGVazLFetBWXJeq9ZOW6sbmt308F1bo5edM\nAMzV\r\n=H1Ob\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCQRLNiGNxvm9/3EhYZNTrOYok6b15cH3NYKMz3GljXlwIhAMSN0fDm5uR9+fIDfeTP94CP12wMwRiNl7XXGGzQPqvG"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.0.0-beta.1_1530571477071_0.5896554751755603"},"_hasShrinkwrap":false},"2.0.0-beta.2":{"name":"nextein","version":"2.0.0-beta.2","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.3","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.3","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-stringify":"^3.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.5","unfetch":"^3.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^6.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.3","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","hastscript":"3.1.0","jest":"23.2.0","next":"^6.1.1","react":"16.4.1","react-dom":"16.4.1","react-test-renderer":"16.4.1","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const nexteinConfig = require('nextein/config').default\n\n    module.exports = nexteinConfig({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `nexteinConfig`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst nexteinConfig = require('nextein/config').default\n\nmodule.exports = nexteinConfig({\n  // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","_id":"nextein@2.0.0-beta.2","_npmVersion":"6.1.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-v675eikgSzyBnwC/IZ8heBPw4Au7xmSDegbSWVxxddntKptZOD/oJSrUeiHcjkjQGR0CaPbrIWCah//zS/2R0Q==","shasum":"afed40da15b8869b31b9051ab4db58b01e42bb9a","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.0.0-beta.2.tgz","fileCount":25,"unpackedSize":67173,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbOuokCRA9TVsSAnZWagAAF48P/0ZkgBZ5nu6u01wRC+Jb\nt8RVq051v5JxoTYK6fX2Z0mUwkm87jE3TJ8ka2SGM4tH4lhZGAGq04vG+xRd\nqPjFMi55n5fLgRtxyio56068d7DSqnLoBpO44jvo0DbIUTThbSiqE0BuAPa0\n4PCy4LBl9ayu6/xPGd+ro7p5+FHnSGxk/bI6fmp4d/v+mGqxOutXz+unE6VD\nxtmkd7Awnqk6EeYTasnA+qxNvT85FrpRjwJoOhxgp+hOKMGvgELx8bf7N/ZM\nrxHsniJhLqpnKXITxcvU2ubneiWWv7tBlsSxfo9Q6WFMFsp1cI0eMYT/yYI9\nwvyQukH7RuV/FmmPYtdQxMLKsbCQNScgTbUkzcr6m6NS7YspTpcpOxd/zsGC\nOEqhEtAPr19jKFh02RFpQrulu4Z1nUqYR2B0PpyVuswDj4Li8qL6AtwAcD6h\n2kDrl53DTNuGVDze1MZhl41nPY2w9Kjcw4G6nODGwM4SMCJinS/5YmmwVcEj\nhBkUCceIKiDxQGEkdZ3z0oHmUbvZFLj6Nuy5tqVswBAB7Gmxk9MZMii8nxox\nepJg/TEaRy53VL0JI4ozF652MCC0UYqqymfGhNLMmzg0FwF03lq4ynkGfc0j\nasbWNGwhiMIyhTZ/x1THfBOifGv1phbR2mVLrtgi3bol/LNufFOk8nqVxBDg\nD7WJ\r\n=8fqH\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICGFTt+wPeGRVvU63RYX/BGAPaCE71jWtNMMWMShZ0MdAiEA9/hPxoyvd8fLRQXneDWXWdmqp/l5ILp3RPYF5jgt960="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.0.0-beta.2_1530587684038_0.9486219670975133"},"_hasShrinkwrap":false},"2.0.0-beta.3":{"name":"nextein","version":"2.0.0-beta.3","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.4","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.5","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-stringify":"^3.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.7","unfetch":"^3.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^6.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.5","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","hastscript":"3.1.0","jest":"23.2.0","next":"^6.1.1","react":"16.4.1","react-dom":"16.4.1","react-test-renderer":"16.4.1","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","_id":"nextein@2.0.0-beta.3","_npmVersion":"6.1.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-WeTIsreowz56NJXCPiXr+xYLSCt6d5bPI2E0o/3WF+69GWVVu7zOsZx5GipLOJXzzvVbLBQ5wj6Kf1hQRRpZUw==","shasum":"9efdaf928669b0cf73045e303f35d1c3bee22d21","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.0.0-beta.3.tgz","fileCount":25,"unpackedSize":68933,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbRCYhCRA9TVsSAnZWagAA0BYP/Anb2iFJpFZXrXKCCr5M\n90/ZMRaidVUyAtloKz9viy6sh6yq098CsNfMzZZ5qqP6D023UfLh4l5ookAw\nXb4Cqc+WHjIqiCXomn8YkoO4s+3nFlUam/3IHQIICGGSQPqWnf5yz3jo3jlp\nVUVuWs+c1QPFsxjJlwafVIycSbwAwBpV20m+SdP3SMS1wTUKjdbg5RLJri7I\nSh3N04cPNZ04NjvjWT81aXovn8RoVXPLjKQGeUX6c1ovYGcPx/mVXXsLmfw4\nL3GYzUV0XPtQIIbU3ECvVEuiehIy8JY9xwRMNlLcHMJCo5Q3Kd7BH/f5z0Fv\nlvFykJhyBNknyPpSvsxhT/VOUTQ8qmFoJHLWlWJVf0LlMmwSqRsIsrb1eeVA\n1Hm1k/pnPoq60XZ3fd8UwGKTn8nzlBHzDFSvNiXBrYJwytLX60jWw2+d1AVJ\n5go2I1ykC1+b30Ut5hAJ//hKtvFnQmk+9U8oHQBPTJQQD/HbrXGLFRJbP68D\nOnXlt+3/Uh49/Gz5/VIAwGdmZlOmtXkbLidvNC6Wv2gOqkfEkKrvP8YiWuxG\nG0C8WdzYF7D7+8EV1q+2gaLYWtpTt4rgH75p6I3oSVfuEtLQdFdmLh79lsQT\nJMsB2i0qh7ja9EHhOVwp3DgVLUL4tPtol77+7+bM7TbAr9X/+cLvpis+M3KF\nVprp\r\n=qqzj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCSy7WJqSYIPcR5qCaMawRxSKl80PU055r6Lmwhn6hGOgIgNUQpSfAW0fh/Bf7Lt935Nu4UlxKu5i1VAelIeDziYi4="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.0.0-beta.3_1531192865416_0.7464370523714077"},"_hasShrinkwrap":false},"2.0.0-beta.4":{"name":"nextein","version":"2.0.0-beta.4","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.4","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.5","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-stringify":"^3.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.7","unfetch":"^3.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^6.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.5","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","hastscript":"3.1.0","jest":"23.2.0","next":"^6.1.1","react":"16.4.1","react-dom":"16.4.1","react-test-renderer":"16.4.1","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","_id":"nextein@2.0.0-beta.4","_npmVersion":"6.1.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-wZ87Zpopm89dMyPR/m5eiQQlnYs2Qn4zMNnLAgO9+GeAMvIkmSfvPTVF5ufC20xNlOh9jaJbH0aACW8rEQACig==","shasum":"c0b6249146610a95b52c4775ede900e0f597c48b","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.0.0-beta.4.tgz","fileCount":25,"unpackedSize":69535,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbSBYgCRA9TVsSAnZWagAAXvEP/2Iv+iqI8J0+PmslqhwK\nc2id4veUm1xEge7Tj0jUXN/FRKialZLARt3/2w+aGu4rcpdF6WiPnyfGqz+h\n+OE6aYt+gzSxTDJ58nKuRCFZ7X4NkIHqTHRUmZoHJ4eMsD2t8PNDZSnG0Dh6\nZxjjmtXhhEhuEzEl17JeRVMN6myyrcRR0KbU6XeReJLYoO2BoIr0VfZxR/fN\nqzJFLAdkvg+dnjREwsSJJ1+IB7OeO+dx6mmqlXbxF329UTeHMlPz3wgLp2k1\nmNbqJwxTxhSjfGcD8m+shPgEfjiFfAqdXQwazLZy2C7cgyK4YKd+IHw8PIwV\nwKPxOhFFf7x6YOmIbRCPhECi+gqUE1ELrLnNMcXvYpviOwhs8PdQ2wG129Pg\nkd5ThKdbQQZBCAzeM5QpOGR9uGIgDGVqkNlXRU+aRzefJTllfUY9WY9FflQU\n+2VK3ItAughvsJWP6DXYIsnuhmE8m958+ZmxVqClzd+0cG3QuuJuzN4JlgbF\nsxEWLZgVfUsR3b5h8ycm/VBoItX68xPxkR+xg8beI+cLfEF2fz/ebsKYYwIa\nG1LbOu0dUdnbWMZtU9cHFqLyiB85BDkRya163RWImHApw3gXUPpjnc1mGjt0\nXnRZUTrBRz/Pv5nbTJlsuptcvpCHYtC6aKsF1iMk4/Rgekb1eI0SemIg4W2q\n1URg\r\n=Omg5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCnOShi9ApzBsenO0wMqo3b0/6BuGbYII7BjjflGv5KZQIhAP2f8woXnaTPOy6SQaGC3iRkQ752nASDCIWhNmcgoYtB"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.0.0-beta.4_1531450912511_0.25046410326506474"},"_hasShrinkwrap":false},"2.0.0-beta.5":{"name":"nextein","version":"2.0.0-beta.5","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"files":["dist","config.js","link.js","posts.js","post.js"],"dependencies":{"chokidar":"2.0.4","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"2.5.5","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.2.1","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-stringify":"^3.0.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","remark-parse":"5.0.0","remark-rehype":"3.0.0","uglifyjs-webpack-plugin":"1.2.7","unfetch":"^3.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^6.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"8.2.5","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","hastscript":"3.1.0","jest":"23.2.0","next":"^6.1.1","react":"16.4.1","react-dom":"16.4.1","react-test-renderer":"16.4.1","standard":"11.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","_id":"nextein@2.0.0-beta.5","_npmVersion":"6.1.0","_nodeVersion":"9.3.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-B5NJpjQZqytwGNnjK5WROFDjIHZjfCgPcqJWlr5QT2YhlFJxluyhLTJrWhKDSygUagSoRHJDJQ7vJPl1xRozxw==","shasum":"73f933d729d4388a8b7d4d0aa569352949d71fee","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.0.0-beta.5.tgz","fileCount":25,"unpackedSize":66937,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbYRZECRA9TVsSAnZWagAApX8P/jas9FugFrENOdZNaxTG\ntFWRZyD+AQ0e/rg5876voqdb898UQN4U2MJUQtfstgNqncUSNzjkS1nAB9cd\nLPshwhdxh691Zza3F2zayZx8d2Eh/9huQUJy/sMcoy2r9KIftqDV9XuNagNf\nWogcSx5/kbYR6QnDamAtFzDThU3bl/DyT7XzTpSgtiYDa4lGNNAyQK6mJfbl\nQVWMw+whiuZQHOTtLCLVl5w9Y0HqCyJT5bh+UK65xFzcHStzjp6+WZF3d0R/\n4tUyPWrM4EcEDcZONiYhnvALNOxaIi6wQptAcU+oeYhurOACXTmt9uhk6f0P\nQUe5Dbd3AYolspHWCONx8WcnkZ41Kw4WvjzyPylxwYiYI73xHMVu77cF/flX\nRfZIwxrsDugQVuqFtK/dVEYkZYOvb/lGw0SXkzapvbLW/TXHB95rrkvwc0IT\nwS45uy8mH98IlKCU0t9UN+QOv/zDgw+IdVOa9bBh1DU6W19AF6uwyx20Q83f\nE0wDqQXXxktyj+8xWaiqUrNdoMz0YTTm457vEDobnSaHGjRQMwtUK8fYMcJq\nCWuOpqJmOhUteUl0T+8OqOLT2OtFth/bMc1ZXK7Hls592T6yTZhuhTfi/uwV\nBIZJvyMAm0qWY67+MwoMPewEODVWXpsdKWeRoFqoy/QtKcVYfvU8LH273OcF\nfDQ9\r\n=rRur\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC9RspXyeltXktKV8fhc97WyQwYtKrdEPTosAUY2z6h1AIgcHmpjlUp9CT/dKwmOlD9MOjW41z2SLb075/MZPds1Gs="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.0.0-beta.5_1533089348369_0.1994852328139194"},"_hasShrinkwrap":false},"2.0.0-beta.6":{"name":"nextein","version":"2.0.0-beta.6","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"2.0.4","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.0.1","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.4.0","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","rehype-stringify":"^3.0.0","remark-parse":"5.0.0","remark-rehype":"3.0.1","uglifyjs-webpack-plugin":"2.0.0","unfetch":"^3.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^6.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"9.0.0","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","eslint-config-standard":"12.0.0","hastscript":"4.0.0","jest":"23.2.0","next":"^6.1.1","react":"16.5.1","react-dom":"16.5.1","react-test-renderer":"16.5.1","standard":"12.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","_id":"nextein@2.0.0-beta.6","_npmVersion":"5.6.0","_nodeVersion":"9.11.2","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-QlC6qAd2Z/3k/3DUdkxzV2b+Q1R1M1vH2Pm4NC9sfOU9XXrjfNe3pT4W43MYr8PFU3YyeacbNim54Xn4Sr2B2A==","shasum":"d656d82081fcf59b91f1beb5c6a281a564d2698b","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.0.0-beta.6.tgz","fileCount":25,"unpackedSize":67001,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbnVhvCRA9TVsSAnZWagAA2doP/RKNuYR9ZW+moq4MdG5P\n2pYZuMUlJ1U6LY1PpsZe3UJui0pMGGW2vbQO2j7C8AffjxXW853itnrCqjN9\n+GqippS4hMfa6iM6qurXmynGfN9mrFqY8KfWJt9NuI5c5FvycPK2ON1soeEZ\n3m8POBRs8UePAagjoQ0skUY74sDKLTl2CkUtP4DN5Fp9mt8TVC/1jK0eOTWX\nJ+6Va2yT4mUMV7ziCh88d6JDKTMCyccyiaTnjNEAIMsrEtiwbaslgApHVrwN\nsxu3LC9vnFlVhkEaf1pXBKiE+dw9tigpHrHH7P6re9gtmenRVs691dTvds9/\nVmCgd0JbyWFkvL2xTB9g5VuaVTmlDCTsvPaNbDO2wfh9ZHzpeaAoxR9aOyAL\nJ2GBjBZdc0iqXwfrbv9OAs4ERuPpoXLWVObmU+rRH587t7cGcfD2B5h2eq0S\nUR2Z5637CMBaR2mYyeNiYmQvPY9a9i3BYCZj0+hOkrkqAmwhjdOT+4WXwFAC\nXoPuXzY+tvAjAdntwTlKsF7GQxWuD4NaI1EOfC9tYnhtqIm7vVbuD/bijgvZ\nErOaqBAom9rFqRIABjpvmj8ydPjQevOa/w+naTLAlwTXi/fPBPKIU4F/wbJC\nzdP3Wpeg5QdNS6QIrPmbwO8UpW68QW/8wTkqn2gbljDYcDCkpmbmgAfIq0XQ\nlBfQ\r\n=KqKY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDhchyN20j0l9hjcXVAC6z5RKoHxnMO2+5NEylQh9TAkAIgfUDXiFCKiEj1I2jortbDoogsDA0WDlrqNb+yK/FfQzk="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.0.0-beta.6_1537038447248_0.7216944861771237"},"_hasShrinkwrap":false},"2.0.0-beta.7":{"name":"nextein","version":"2.0.0-beta.7","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"2.0.4","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.0.1","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.4.0","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","rehype-stringify":"^3.0.0","remark-parse":"5.0.0","remark-rehype":"3.0.1","uglifyjs-webpack-plugin":"1.1.6","unfetch":"^3.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^6.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"9.0.0","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","eslint-config-standard":"12.0.0","hastscript":"4.0.0","jest":"23.2.0","next":"^6.1.1","react":"16.5.1","react-dom":"16.5.1","react-test-renderer":"16.5.1","standard":"12.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","_id":"nextein@2.0.0-beta.7","_npmVersion":"5.6.0","_nodeVersion":"9.11.2","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-fKNgZ8diPh/0GjU+SZgRQjF8m5b0zPS/CnFCSl5J7gMfOEn44obKIGeQbDp/8NOgZyM5PKmP79h+3xdpRpmsiQ==","shasum":"8a7efd9ffe0b779232462c2c3d6330fd5a85f6d3","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.0.0-beta.7.tgz","fileCount":25,"unpackedSize":67001,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbnmXfCRA9TVsSAnZWagAA1u0P/1ZuTT9vDraXCLkrd2R6\n2gK5+MK72uYcVaoGsX+bfdut7XwdZrbHRql2T5iymKyFZFN1gOEpBdVAuDP4\nnK+LWOeqFbF1FDO7uZkczkN5493L6X655gm7NwFueGcrPBdk8HFH+FEBwrfq\nP5B1vYKaYbVQasI69dZJGkxKi5qUvOJJABpbaqTn90lXpnFD30Axrp0KEHls\nWx0lWFLLsxC4ggz/eir2jQJJ6sJX+8Xqqf+TsKZUA6TgyvFAhSyDPBLwJ1LI\ng7+IasfaJZDmQ2Y9ejGZZc17C1vhTfijz6diIGngx6dCXbqs5S5+vH4E/vub\ncau68yUm6qzY54wUckk9UUOk1Xg8lPKHDwgBhScAxO+Gz4N6F7fTQiwFDWek\n2k5y6QHO85J9C6RsNM7IBfV0mvAN5kkvuep6St/5eMDkh3HhmXM5Dq/UrZVJ\nIjspM1DArYiznTzynrvaPTOYxYYCeLM+PCWRaNl05Q8/JW4FNoRZe4kx7q1i\nRd19vt8xSVrINN+/2VFqyg4sZYTOdnrmxWJzIj5dIKSSisoXjFidV0lPeQ6F\n5IRzgosoJLeyMkWEecVYrZ8zUYDkYUR5Ju5ySmG/MdrvqCMR4nzGjoFCpfyC\nb1WKwndWvil+h+teNc+6wFD5P3VtA8x2ZK+VX5kp6uYFBRqjslsmNhmFsCz2\ntG/m\r\n=c2kj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHf0XFitT/nckLmGnVCUkQn3A83p+4fcImPRQcSCKSZ5AiB7ysR6kL89gGz45eSBnpfOW9nvgg4uO8rbAtNtLBAT1A=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.0.0-beta.7_1537107422425_0.7318052002776321"},"_hasShrinkwrap":false},"2.0.0-beta.8":{"name":"nextein","version":"2.0.0-beta.8","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"2.0.4","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.0.1","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.4.0","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","rehype-stringify":"^3.0.0","remark-parse":"5.0.0","remark-rehype":"3.0.1","unfetch":"^3.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^6.0.0 || ^7.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"9.0.0","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","eslint-config-standard":"12.0.0","hastscript":"4.0.0","jest":"23.2.0","next":"^7.0.0","react":"^16.5.2","react-dom":"^16.5.2","react-test-renderer":"^16.5.2","standard":"12.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","_id":"nextein@2.0.0-beta.8","_npmVersion":"6.4.1","_nodeVersion":"10.10.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-0ZWNBKed1hkYzHjrKDB1A8VrYLWSkxQBQAMSzphl12G6UOu9evnGXbyGwtyCOWIYkMKKMc6+vbYMDM4PudZruw==","shasum":"ce6ce549f2ce6d82c75e67fa1b4d53e2f0fded6c","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.0.0-beta.8.tgz","fileCount":25,"unpackedSize":66830,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbppECCRA9TVsSAnZWagAAOfgQAJ6m2HPXGOHwiuFFTAXQ\nFSok2f6uxjB94FUyhW2BDsaUQ0ZXqdYwV89k/4K5BEWYL7q5BtlQLNcnF7k4\nGxvUSC6LM4QkcgS+5GfTrvKUD2FggtZtSV+NzvSQ21oKcIVuUBvIbngKeO9p\nTmYOBFkoJEzUzm+detX9fmGQNY+HjY153G//VoMR7bcmBUc03IGRuR7PDFLM\nfojp7W1wVVE0jsEeUzNvOGLHtnf/SnO1ois+NViDr6HNFhH9X3cAPpbZag1Q\nebaaODnkweRkS2CNoXGxhBagkkLFn7odNUDQ9REQDd2/bu1RfYj+2LPZ0X+j\nh7fvF43cuNF8AEfGdHT9DlOtz6TMUPlGWbsOPPoeGkKPekxYdhT89Xn1Xv7E\nv6FgT7b+jkcJenBQfaUnsy/CkNCYEmKuXHfmHvV+wcPfLPon45hmXxCeSQF3\nYNd+SpfEgH1TkcSmjQ04gFAveBMewHyrq4DUy/SXJJtzX+I376wwwGa2uxFh\nH8Q1Ujl6gcte/A231Y5LYkEjSaOiwn2xMiujnKEnVU4pNtNzuWHdTz2VOGur\n98CYRu6HK3crTToKlivU2LfcWQv0dgjnLq8p33dsznJTzslNujMqrL5D+5gh\ndQPKKYwIMlmA6A/1jIuV5nOuPyQo0+VBS1gvjKdVzVZ10C/98wNF/7AjYeuk\noODx\r\n=ikDS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD7W15f+QgL8GHjTA3chU7wGF8JO6AGY2XezpY6paCAmwIgUfi/Qu2ylGz1bxvBIrH23Inhy/gNF7IYJIxbvroD/tc="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.0.0-beta.8_1537642753671_0.9752162733268783"},"_hasShrinkwrap":false},"2.0.0-beta.9":{"name":"nextein","version":"2.0.0-beta.9","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"2.0.4","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.0.1","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.4.0","pkg-up":"^2.0.0","rehype-parse":"^4.1.0","rehype-raw":"2.0.0","rehype-react":"3.0.2","rehype-stringify":"^3.0.0","remark-parse":"5.0.0","remark-rehype":"3.0.1","unfetch":"^3.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^6.0.0 || ^7.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"9.0.0","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","eslint-config-standard":"12.0.0","hastscript":"4.0.0","jest":"23.2.0","next":"^7.0.0","react":"^16.5.2","react-dom":"^16.5.2","react-test-renderer":"^16.5.2","standard":"12.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","_id":"nextein@2.0.0-beta.9","_npmVersion":"6.4.1","_nodeVersion":"10.10.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-S/9TuQC331I+ErTVe8pq6T0ot+D7uTdIAc/60NqvEalcT82K8wOAsPpNZ4/123PkMTq+4ZzmUACLZCbMZCFq3g==","shasum":"4dc88d762f802bab380597e4a1fe260d7ada72dd","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.0.0-beta.9.tgz","fileCount":25,"unpackedSize":66969,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbppmBCRA9TVsSAnZWagAAqMkP/R5hYS9puKXnyQVYgOSJ\nLiNwydgSy+EY+MCFbVI75m4p/Acp+umD5Rib91CKrHSTWU+hMrNXSzYXRBcs\n4AElEIVMBplYtrygJZGFf5QADjbCDZ9KZMCfbFprilIK1INu/Qz63hGIU/MY\nuQGJBPLCdHxBpEyfJorrPTytoWu62J5CRYY1sN+Q0j/F8mu1ciC5zicIGGhq\ny5wXP36mDcm8kXUi8tRuxv4/y9LFV5afLmLBDiJMU1xGVHPYEqPbtcaDQW30\no1Fhbh0iDNYnTw01x+H9UYZ68RPjdBAEPLQNUzjagbxtKPCJPiLrYFEKpmjE\nGSawj7phkOxQvIn0kf+OArGlEgjSxMVQqC+b7MiKGLlFSJLM9CRNzMgT81xo\nlZuWjaotj15ZpxrHjZQF+rrWmpMz/glN+yWMP+JNXw6l4GDkgNlF9WZQ5LNj\njcKgl6PQ0CZrkZKtqIt3ZdqwuMDhuT8gG8hRw/Pi+QCqprEN6d2J57Wr3pJh\nkKkXTcl9yMoqNHq04tJ0IrAtqrYNp3VLVOpvJHWmOIipk17/IDxcYrO7IsgA\nVMZkYMfDosusmF8HtBhffVaMFr8IFGuglsk0jnocazf0PGw/GCPOPdzMviJN\n/3dXo/GwJrNO9HOkYJpgV442wrUbBx+l5mVUahk0EPQuRMuofwWLUqglYiXd\nr25G\r\n=VSgk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDDd+a9IVoDyWH1MDhUzih1QWxhKI9N1uk2sFPoEX8ZYQIgRPBm02/YhIUPnKHc62bxFv5/CI/7AmbIx0rAouFeyuA="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.0.0-beta.9_1537644928846_0.8701061788892912"},"_hasShrinkwrap":false},"2.0.0":{"name":"nextein","version":"2.0.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"2.0.4","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.0.1","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.4.0","pkg-up":"^2.0.0","rehype-parse":"^5.0.0","rehype-raw":"3.0.0","rehype-react":"3.0.3","rehype-stringify":"^4.0.0","remark-parse":"6.0.0","remark-rehype":"3.0.1","unfetch":"^4.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^6.0.0 || ^7.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"10.0.0","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","eslint-config-standard":"12.0.0","hastscript":"4.1.0","jest":"23.2.0","next":"^7.0.0","react":"^16.5.2","react-dom":"^16.5.2","react-test-renderer":"^16.5.2","standard":"12.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","_id":"nextein@2.0.0","_npmVersion":"6.4.1","_nodeVersion":"10.10.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-d4LJJL9hkS8NbeDEyhQ6Hn2Gti+3Dhosi2Io7YUwTuQQIRTpEzNXPhAkIfQX172ZzaxzqF1OKlHSuqnoKF4dCg==","shasum":"94008c295cea5dd617934db0df2b26e53f71c64e","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.0.0.tgz","fileCount":25,"unpackedSize":66963,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbzlibCRA9TVsSAnZWagAATdoQAIXTgczreoLLlRwOT5fn\n8GixXoMFTyw0+KgGCKjcBBeM5L8HDUsgt/JtFiAUnHlS24zR5JkvZQ+M8MtJ\n9VBaBgRqE8FXEK74RUpmC4vAPVyzufczrVVcSwZ72eREnHYXMtEOloCfzxRS\nInIDfowTLwp7iFUL/QHLAR6Klvse8l+XePM5ISwyuFBYVA32LVnAAKM/FlEr\nW6EnvPSlblISM0CQqohjUoMrCsvpB2UPQRTFXScItDpGFYHAqZ+X3vGqfMT0\nXMz7WaXDxxGfdSRhbaXQezihzc0EmHGeKNie1ApBPeVDs7cOQoNMf/EJD8GZ\niZeQI5GmkBUMxC58Ssv5fKNVQVVMnDEDtoFBzTOgCKivIYArbrh9ECGpSg5p\nVD9hd8Xez0n+yDDxxgwA7RGLETF5S661LVUL5DqnVH7YvSJRmRF2+TqAou0z\nVUTSx9DILi06i/edNPZiSRmJfwOOaCw25AfeTUOdzBi6YvPpeP/IzsQ5BBwo\nQlBHA8EzQtaiBqxSMkcjUY930YGbkuCowJKyfLfQyK18J1/2fCspNdGfOJ22\n2tXXY652bJ0AKlxvgW0OMHSUtL7GlMdvc/Vu3Iz2aamnoPts3XC+5H2T7fZJ\ndHbhFUw+TiCAcfC5ZVn9CNjlvT3C+usBHKxO0ON0v+QMXDzK9rFig+OeHdHZ\nnL7m\r\n=UOhJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD3v+PQ8EFh971617AOBrf30RJ+Klhf2DIm3tCfYFvygwIhAPItCxQoi7MjDzczbr7lgibpVfW/RY8Ze5i1YhJjzqZB"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.0.0_1540249754160_0.062077967594632355"},"_hasShrinkwrap":false},"2.1.0-beta.0":{"name":"nextein","version":"2.1.0-beta.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"2.0.4","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.1.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.4.0","pkg-up":"^2.0.0","rehype-parse":"^5.0.0","rehype-raw":"3.0.0","rehype-react":"3.0.3","rehype-stringify":"^4.0.0","remark-parse":"6.0.1","remark-rehype":"3.0.1","unfetch":"^4.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^6.0.0 || ^7.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"10.0.0","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","eslint-config-standard":"12.0.0","hastscript":"4.1.0","jest":"23.2.0","next":"^7.0.0","react":"^16.5.2","react-dom":"^16.5.2","react-test-renderer":"^16.5.2","standard":"12.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","_id":"nextein@2.1.0-beta.0","_npmVersion":"6.4.1","_nodeVersion":"10.10.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-/lMzd3gW/4YCKQFw5Lze63VbPivJk3Fg0BPr3IYGeZKderE8tEUPB5XUFj26w3eWqLPIPlp4RS2Wm4lQ0lekAA==","shasum":"d18e77579ed33e58c91c93f0e3b86cefd8f3c636","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.1.0-beta.0.tgz","fileCount":27,"unpackedSize":73677,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb4h9DCRA9TVsSAnZWagAAzZkP/1kKHpDNRHiS9ka2/vSN\ns7VR1ogKKwx6sH6YpYTrsIQgCwrJDhyHb65R63PgrlRjvWyYVhj+IHMskavY\nvWGZ86BsoIu8TDbpnXNzoDH6ZL7ahuV0dc3DIsPNUBW5wsEBponztQVUs7kj\nHIE/pKWuFCCOpJ9K6HuBvhbPfjQmLnRm1EOEzWZM2ovioe9tHzGvrEOEaN15\n+1cnU7Ov80+ST3tvZvXKqpPiGL6MY4jU8Am5IyfhmNPBF48S4+1lxuplTtc8\nKcMC/qGFENShd70WW7k7aiZXxvTc0Fde6Dv6eUohS8wf+HO5pVBvtPp5yKpc\nNgeiHjuQZdWp4mm2wp3WDZphDcPHt1v/RaONPrFq3b7tM0aBL7RbUrwvUGNU\nzCDiVBdyU+bucPor6qg9KU9Y5O/HXAi72Irgb5uuKgodG2HbNzbQuB7ybYRI\nROzWNkNHhVwVGQzQi7Xk4IHfjyv6tBEbunmkEzcEWMKEemwQjUtOnv4x8hAC\n5iAr2K4/hStGDKuEInAAkVaT8OQAFPQGlfi7qUHRnoH0tbW5zkbZfh0WimOw\n0vaQnci4By/3RB7uMdmc6dChT7AHDzUVWep7egRCaPNYYOikRvY5v6N8vuxX\nzFe9xgtoYIYBldl8JFErki39YuR19QrjSscl4z+/JDHRw5mXVwugph+gfKIT\npLJH\r\n=EpPh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHTlfmqn/CO/pO2wDoxPi7uaecp5P/U0wNVQrF6wt5eGAiA3E0QBKGM/8Xt8sSKJTHhgzyo2UFUbYstskacFzWIQ0A=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.1.0-beta.0_1541545795026_0.3544446470335243"},"_hasShrinkwrap":false},"2.1.0-beta.1":{"name":"nextein","version":"2.1.0-beta.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"2.0.4","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.1.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.4.0","pkg-up":"^2.0.0","rehype-parse":"^5.0.0","rehype-raw":"3.0.0","rehype-react":"3.0.3","rehype-stringify":"^4.0.0","remark-parse":"6.0.1","remark-rehype":"3.0.1","unfetch":"^4.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^6.0.0 || ^7.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"10.0.0","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","eslint-config-standard":"12.0.0","hastscript":"4.1.0","jest":"23.2.0","next":"^7.0.0","react":"^16.5.2","react-dom":"^16.5.2","react-test-renderer":"^16.5.2","standard":"12.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","_id":"nextein@2.1.0-beta.1","_npmVersion":"6.4.1","_nodeVersion":"10.10.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-wUzrwwg5jOdwDuODypV7tKCRwpTxLpNGhWx48MNArWEi9HI4ig2sMYHNYd9ZWyacuhvnqgjZR7N6v0Q+XD6XZQ==","shasum":"34f93fa1a4622af13a3ad1d63ff390f243b554a7","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.1.0-beta.1.tgz","fileCount":27,"unpackedSize":73683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb42MJCRA9TVsSAnZWagAAYzwQAJ70iBL2Qt0ydifdjqvF\nGv0OBOTwZANYkAavRdBWZN2maGGoKTlMe7cupkD1/Ymk53jE2eBudabiZB0s\ntlcvzRcvuYGsAmr1ZzqCcnvEUgJXaIMwilATAAYQGMSUezB46vD/TSCOPMPz\nmribnPsdM+MwtxHneYCDriKlo+UuHfXtQhh4Nk6OPFYJHvkmRLbx1Hc88Zzk\nlz547vFtOClD2nK9EF+GY65QTOztwdwji4Cal89R4FPn3mIH+goBbXOmJqqv\nuiMjtJNB9bQG97DvEKxoQ2y5L8m+5azRYgTT8C5CH3+yQMkrNU6JcIq+cC3i\nknKRBnxlBBZFH8+nd4pVzOZS6CK2A8W9cccTAlCANG7E6Ci2oe2pqkV9LG3+\nbETm5ALcNaU8xOMT8MNp3iFLNJEWrWo/BmmSmLUPnMKsIi9VCyBmtgQy1kL2\ne4rXjeh57woyr4ixzCP6p80QD/Q0hG1VIC1wAhdoiejwHYTz8DVg5j2UBDok\n4mfOUVJ1xCJaN+Onchbdho758/3zZVyfXy2TVIH5cRMfb0IeTXLp9k3cc9AF\nbF6ZvqIqwl+pF8gke8JKT9mLPje88d+Tg2vD6ihE6ZYk1tnsuc8clm/2gubY\nHNLxce1ckbU7uuUeJPdZp9fxsiovtsWDsdzpGpgrS0yOgvIla6WIpLQ4pOPa\nV7kY\r\n=S6BG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEvl77Xn5eXcKFXuixIJvDv+z08FMVUMW37G5m64ScF3AiEAmZHgdIEUWCHot/ymR3lnsFtjQg7bC1SkQ5BLle77FYg="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.1.0-beta.1_1541628680652_0.09984227421291036"},"_hasShrinkwrap":false},"2.1.0-beta.2":{"name":"nextein","version":"2.1.0-beta.2","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"2.0.4","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.1.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.4.0","pkg-up":"^2.0.0","rehype-parse":"^5.0.0","rehype-raw":"3.0.0","rehype-react":"3.0.3","rehype-stringify":"^4.0.0","remark-parse":"6.0.1","remark-rehype":"3.0.1","unfetch":"^4.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^6.0.0 || ^7.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"10.0.0","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","eslint-config-standard":"12.0.0","hastscript":"4.1.0","jest":"23.2.0","next":"^7.0.0","react":"^16.5.2","react-dom":"^16.5.2","react-test-renderer":"^16.5.2","standard":"12.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","_id":"nextein@2.1.0-beta.2","_npmVersion":"6.4.1","_nodeVersion":"10.10.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-ViU0fU8zdZotlrtqXWcNPLE8B1o678Ehh2zF/8lkxhGTbPqqKH8nrdgINZ+rYoatn4T9oOPOzG57PbruwV23/A==","shasum":"71bfe97a725b1386dc6f28a7416386fcf01f715d","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.1.0-beta.2.tgz","fileCount":26,"unpackedSize":73553,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb64lfCRA9TVsSAnZWagAAyJ0P/2y6sEcchY9egfGIc9GB\n6BouuqIxL7AsOpAlAOo/hMtibLdoyCq3P7AYHBF/W2eLks79ommgu3zxDWvN\nLIXP+Twr5LjgSr7YC8RQE7+7nGcyF4enwnuLGKT5vu/hIKJr7pD8GIdkD/Fk\nYbSBO210YVyecEfn1EgE//77mdrjHi0aIZ3XZDPWTKYp2arD//202/Pfg2iR\nr0/2rDWoS1xuGdPvK4lvMjSiLIz4GsmbUq1EPBcnpQu4+0oaM8+21udC6He2\nLbzfdGJNvDr6zOTuVIT7cuSiIO3lLma2EO/Rces6iHA3pE+UW4Q9oNxQYbLh\nI5zx5fGGCNzenrDR4e6qKC28qlm9iUqcho6mxblGlRBGqNWFnTjFjoGObYLk\nyvEcHCYQKdZJ0MObrpMj3WX1EqW4K+1O8uak6Y/032iuHUcQ3A1eqigh5fro\ntgWmLt21YKtyNtR5x9qvWPvns3I1iRgVESFNNhfjNVDJEKodgrMSDgE4yp+z\nAijkBXRiqw/XgHu6l5VmnBMORuBpjufAcRKjM11/XKnoaK+bxUT5eqr99Khi\n7JofDNH5clnHZDBJaSmWxZ5yElmlerJbJcFM/IusUGHK4b4bsLvcs7VOksO0\n+lSP3ffzcGxC2nWU8038BROsQCTDODX3sQ+6o2LmzfmXmEUL0weTHKfaCNn4\nrWf0\r\n=lZOt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD5/G4KgEfdyYBTDW8Ojcgb94Qn7b3eVfoq8fTxAa1T8gIgdJckRjkabT9ExxE3GmqMqEStI4gmhYRT4e0ta2D8FV4="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.1.0-beta.2_1542162783041_0.9555279203233642"},"_hasShrinkwrap":false},"2.1.0-beta.3":{"name":"nextein","version":"2.1.0-beta.3","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"2.0.4","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.1.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.4.0","pkg-up":"^2.0.0","rehype-parse":"^5.0.0","rehype-raw":"3.0.0","rehype-react":"3.0.3","rehype-stringify":"^4.0.0","remark-parse":"6.0.1","remark-rehype":"3.0.1","unfetch":"^4.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^6.0.0 || ^7.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"10.0.0","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","eslint-config-standard":"12.0.0","hastscript":"4.1.0","jest":"23.2.0","next":"^7.0.0","react":"^16.5.2","react-dom":"^16.5.2","react-test-renderer":"^16.5.2","standard":"12.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","_id":"nextein@2.1.0-beta.3","_npmVersion":"6.4.1","_nodeVersion":"10.10.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-um7877fgAL8Fy3ctg5SMskjYUUhI2ZH/r71PgTmgmL3wfy6ZXzL5r4Mi4JHS/FWH6oi0H3UcA3QPF+SrHhwcGA==","shasum":"c4046ff1c1f1c76661160708cf53e54d4c52dc16","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.1.0-beta.3.tgz","fileCount":26,"unpackedSize":73810,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb65EzCRA9TVsSAnZWagAAOgsP/0CWXgtVgyTgF0i5+1VR\nK+ETC2bpHSKCyzS5LG+PzX6e+W3g3VnSPLyWuJ/sUihqHGh8DJQKXQIFeLXD\nG9p4NdQcaHyAax+ONlgYnQr9fFWDeKRBWKaxAoaqiOvK0G8Dd4FP2tiDvBE5\nlS22dOINJ6Qdh5SW0o5yWW1t07DXW6LKC0PhdceGZKgmCN/gIJlDWmn+6NF1\n+Y8a0DRu7uLUVeZ9ZlsYFuLtfH0+qC5qM5anlrFldrD3OCDvS7cMFUWjiVn4\n52BadHBex8auCu0R4tJg1eoD1fGbOIz91bsAHp82FozoqR6De3fnxBkLIsv3\n0O0h+Hr0KS6ig42P3gQCBMnd0l3PaGeHwZbBUkY5zkJO8RLdhxJTuCqVl6p4\nAWOjo7yobwUNz6mA7ISb3uU/VvU/xaLQO2Ve/5JzUOawdrZfLCsUjclX63Ft\n1AbfPIp/+Xluc6KpH7DA+v2KV62J8LNVx9JbYObF8/RGba+IYJwezwyGZvoY\ndpqaRRu0r93ZaVYkX52QozOQW9nEbpgNcRLQoKJwGjisKAePoDRCZRs1YCVv\n8H1hsjL41rm5U67vk/F/rWb1gnbPen97OiiuftCyiazxKVHb5OeTfbfchzML\nhgocpk0TpRXUA6pZSh+KTg5UUIA/wojTAeWeLziCAAkPVOcVqd9XpL9hLRzs\nF1dG\r\n=ZtG5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBdRumM8OTd1qEUPwQY6JscWxJGLX0oIQHhgtu3PjcGXAiEAxd8nMP9tPrZxWi873ZTGpjAj7aWQIYMYt+IfhWuLD5w="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.1.0-beta.3_1542164787212_0.49649611054688414"},"_hasShrinkwrap":false},"2.1.0-beta.4":{"name":"nextein","version":"2.1.0-beta.4","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"2.0.4","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.1.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.4.0","pkg-up":"^2.0.0","rehype-parse":"^5.0.0","rehype-raw":"3.0.0","rehype-react":"3.0.3","rehype-stringify":"^4.0.0","remark-parse":"6.0.1","remark-rehype":"3.0.1","unfetch":"^4.0.0","unified":"7.0.0","unist-util-select":"^1.5.0"},"peerDependencies":{"next":"^6.0.0 || ^7.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"10.0.0","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","eslint-config-standard":"12.0.0","hastscript":"4.1.0","jest":"23.2.0","next":"^7.0.0","react":"^16.5.2","react-dom":"^16.5.2","react-test-renderer":"^16.5.2","standard":"12.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","_id":"nextein@2.1.0-beta.4","_npmVersion":"6.4.1","_nodeVersion":"10.10.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-ELqRq+cn+akOFQGL5mDGde0r8AaQrp59K0bKxK1RiMab1ai9aWeYPlpw+888GtxpdqjalMWhfhrQ09U5rWzQzg==","shasum":"fff03db1ac223171809f3f309f9abea69c0f23e9","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.1.0-beta.4.tgz","fileCount":26,"unpackedSize":73605,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb8dvcCRA9TVsSAnZWagAAb38P/jZNZLpKwrU+FJrppq/N\nxfVhplNihkMFevyp3edQ9fHGg1Wex152xf16BsCzoKMtr8hKxc4dlDJk7rAH\nIK89HwrowagmJpEQsqyyX0rXbiGmLBzKvmaQgv22VnAgsVtAb2HKa9rKWRnS\nymCVXTr+GZqMWfjH7VUWKMy10o2CGXjm0CIKbcfWTDJ7jAoTNpD9SLuNRk9y\n7shsbc2KfjJpt1qE/HNp9uKPDg+6reo+qdBXYZeSSlQE+U3viRMOEivlyIwG\neQc13mUjALdQJTGCKAvJHfGQ3jS/3S+vdmLc0QoLjVWZ3vJcGg6YEJs59EJp\nQf7KGFj3lhrvFll44qVgy/SXg2zgbyYGYWvsqrsMJgXP0UVc8qHaOrg/I1Fl\naigUuddGY1IVkqO9L00wjeaLDegG8v9BnxU1u5+7StysiRjTACTtkJbwqYIY\n0923ul2WQglEamkkJFYk1hliGetOHg78c6Kxu5su/qvwfdSxDG4/exW3eyUG\numjXpb6hTI4hIjF/YgieBqbqMLkbUtXJ8qiq8eKfB9ssGA3dlnOQQK6kWuyQ\nzFIOcqTidiLLFjPlymAxXeRc47DFane9qkcD3W7J90roJoYLVJbuutQY4m5Z\nN86ESD7L1aumKVU+ZxA9sdhvgCzUJ1Fs5rKZS2kYTSLMmtqGlOVRcW2IZqQK\nvUDY\r\n=d3r1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDGgXhE25rB2YUuR0mriWvog61zbZTAfWwtqzPxp53AJAiBmQDr07HtdZW/4bmVsXs0OmhLxxjtw2Xiyn5FQuqpO7Q=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.1.0-beta.4_1542577115646_0.4359000059858622"},"_hasShrinkwrap":false},"2.1.0":{"name":"nextein","version":"2.1.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"2.0.4","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.1.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.4.0","pkg-up":"^2.0.0","rehype-parse":"^6.0.0","rehype-raw":"4.0.0","rehype-react":"3.0.3","rehype-stringify":"^5.0.0","remark-parse":"6.0.3","remark-rehype":"3.0.1","unfetch":"^4.0.0","unified":"7.0.2","unist-util-select":"^2.0.0"},"peerDependencies":{"next":"^6.0.0 || ^7.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"10.0.0","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","eslint-config-standard":"12.0.0","hastscript":"5.0.0","jest":"23.2.0","next":"^7.0.0","react":"^16.6.3","react-dom":"^16.6.3","react-test-renderer":"^16.6.3","standard":"12.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","_id":"nextein@2.1.0","_npmVersion":"6.4.1","_nodeVersion":"10.10.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-pWLQ7Va/WMjfb3UEjVs8GJzWAoNcZgR/TuDQNy8nWXejKy23YO+lddMspCxeNnE+hVJYDEmSHOwyL9aNSi765Q==","shasum":"2ec7d1b270f2786772ca368b59a8c3e3d2113670","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.1.0.tgz","fileCount":26,"unpackedSize":73524,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb8eT7CRA9TVsSAnZWagAAqyYP/i/FoaRhl6NvAVI1ZoU4\nQCui9uIo0ZL+JUk2st9rDKvHqOIthg0Op4YGbOgFTF6wE2Q5YeVv1nwnyGtl\nQoVPr+VK9MX7BjFXzibMPNPXLnxLpb8dnrTjvkAaUoD4gl/RHX0XIOcScAji\nL2mb2lzpmbglIfmJoJNyyJSt5EH6P6U0JBRTMKGlas5KONH0zKnwWngvlYs4\n098NOxw33/+yqKdbLnSf/BE95WQ/zwIhXHxv0RdK7Fa6/1MxavciqVclY4Mp\nC1xgD/tzr8/mVV25wI95JV8hksVlNYvrcWAtH1HJD+MYPxogNtOQbN+4ap1V\nPmT8W//Sf0CzYxDj9dYI7zbXq26Hp70FZs9i1JaV2zXHOimuuja64XyWaRaA\nJ6cZhNI1v2DAhm+J6AHTK0VAjGxH1XvLs2m/yzZI+VvsoJcXfTaPFExzARWm\nhl7+cIVfCiXgFO3W5E8Pp71McK4+ICZy/WCgdbqiyBk0lWWL2kjESR418lDF\nVk4x0GuaJu9hkfz4oUJT4f5jrlTI+v4HQVUtpbgRTqAR3CroLPIKFgNl/CPz\n4qn4j2FZqbsSsi93ohYr3pf8AJK6rG6bA9nS106eufZ7nOw/GHb1v1z0YVw+\nfsPAfttLkikofq28aglNwDnpNcyLuHu/ZK/zN1DpSkK6EiRWjJfp4z74Bhv2\nmXvo\r\n=TJ+P\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIB4lZ/SalQznSv4c2cBzGZWA6m7EYNa/3YrnkM51VqGnAiBtHky7n/wrf5750T7rcisEMRz4Eo/lTZxIkGc3Mj6/TA=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.1.0_1542579450930_0.8872206857600202"},"_hasShrinkwrap":false},"2.1.1":{"name":"nextein","version":"2.1.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"2.0.4","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.1.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.4.0","pkg-up":"^2.0.0","rehype-parse":"^6.0.0","rehype-raw":"4.0.0","rehype-react":"3.1.0","rehype-stringify":"^5.0.0","remark-parse":"6.0.3","remark-rehype":"3.0.1","unfetch":"^4.0.0","unified":"7.0.2","unist-util-select":"^2.0.0"},"peerDependencies":{"next":"^6.0.0 || ^7.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"10.0.0","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","eslint-config-standard":"12.0.0","hastscript":"5.0.0","jest":"23.2.0","next":"^7.0.0","react":"^16.6.3","react-dom":"^16.6.3","react-test-renderer":"^16.6.3","standard":"12.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","_id":"nextein@2.1.1","_npmVersion":"6.4.1","_nodeVersion":"10.10.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-IznLOxWmZ8hNj6kADoLiWpH6eKAnkZ0d2+QNO+6RLYcTQn9HBfmBl1Gbg5q2rF8ebtXCgi9u+bFgr3vIoNMMsQ==","shasum":"0ae60e5244cee80f6fcbe6e3454335ced2cc4936","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.1.1.tgz","fileCount":26,"unpackedSize":73572,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb9McbCRA9TVsSAnZWagAAf/IQAKJdIDZAKSWpUgDysfy+\n2O3Zsz6qqJxkLDfyELNyY8SR2wHDxyA5i1bpcLoPj9LBgsCqcLTjD7I6WwU+\nRHQpnWSAUSWoaIp+4h2xx/H97LSyEMZA7okWN85wh35yaavZyzz7Bw/MORG+\n7QRhK7wRjtazeBS0ok2RXteI4GwGd0ERK4pExXmGsJ32X97XeE6r60QpTy4a\nc2+I/6P5zUEubAtONIqeS6boESn7vCEfV4kL4o2K/TKr2zP3aIsyXV4BMwXA\nOqEAjTFIrNGV+ewLWFEtid8wXhKAusZxpF2GwPe1+7p8elJV92NWi8srRU/G\nlAthwWvE/6O8g+Unn+GdIpPfj6f6D4QLK1VMSITIlwV4Qe3wJwJBsB4E4dmm\n8+mbinDxkwAUtiEFQ1yReaCf1FgCaIoP7r2CdblGbjZW1SgzotFnHNIbCl9J\nu6xNARFZyBtKtohowvWTgXVco622LB5VEoF2h8eItBIyfVk/bDV+THsU3gnA\n/ts870NSfMLKcsdM5/mN3uM25RNzHGgN32NhM9rgHB5apzx07IB3mQmM1ZUr\npU4fW7H+1uBddEKKO3kmpTl8Ti1uy7MXQmsotkv5BRL2+BWAIKbCOuZXL7Dj\nUccsJTeZaY5T+NrDtYY+aXMw5vuaAQfeSPTUVDxgyzQ28BjWQoG0aFQGfEec\nCq4D\r\n=VFpb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCz0o1qL3xdlkMfIcQVeEN9koj0jf5Cz20nCDOMuplXDgIhAMx/qwTR4k1T/n4OI46oarg33bLQJC2YmzB5ZIEVZ3sH"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.1.1_1542768411283_0.23803869552797874"},"_hasShrinkwrap":false},"2.1.2":{"name":"nextein","version":"2.1.2","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"2.0.4","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.1.0","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"2.4.0","pkg-up":"^2.0.0","rehype-parse":"^6.0.0","rehype-raw":"4.0.0","rehype-react":"3.1.0","rehype-stringify":"^5.0.0","remark-parse":"6.0.3","remark-rehype":"3.0.1","unfetch":"^4.0.0","unified":"7.0.2","unist-util-select":"^2.0.0"},"peerDependencies":{"next":"^6.0.0 || ^7.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"10.0.0","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","eslint-config-standard":"12.0.0","hastscript":"5.0.0","jest":"23.2.0","next":"^7.0.0","react":"^16.6.3","react-dom":"^16.6.3","react-test-renderer":"^16.6.3","standard":"12.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","_id":"nextein@2.1.2","_npmVersion":"6.4.1","_nodeVersion":"10.10.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-fSxoONqO6VGibsJNNer0UlIdev3AyGQjNwvZRSJFmM7LdjvGbq1yv6pGITOTaw3p7zRVY1pUygdc4ar5goXEAA==","shasum":"e9c91ed90151990a60b7b0d67bea1ff27716acaa","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.1.2.tgz","fileCount":26,"unpackedSize":73446,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb9NK3CRA9TVsSAnZWagAACW8QAIAG+hA97zqRjvxXn5YL\niTN6rsi8eqc3HoMecDkt0FrzKRBRMn7HxmvO6Ngq0vP692JfMF1muIiMsggc\nTBlgUQ+xFb42+VKT44BaIyVzIErMwhOHT09Du1DMp8ByUfve5h3/JIdN6TeH\nw+pk/nWjj3CKkNmglbBx7wxv2IHqIRfko1zLXpPY8qU7+PVNDf+I3pBHLJ+a\neugqS9RuupidVdVuQVdOc29gWpg+qaLT5aTlv6ReANKESucKz0SE4Orpm7qi\nJbjpc4oM8MQi4dfOjV9XOqRlGFSnOAy24cDWsdRm9tjfgyU3jiW3fexJn2Iq\nwUp1//11d1QeVTL72eZou9Tez9VSDG+Up9WlRnMDEx7I+6feBROcvWuoykrs\n824tBqTKWt3WU04T+Xo9bjQxc9CStKDLMV40epkM9ydos1y6z5U8R5Yvunyv\ngH2yiYqEwjjtOJqWueTdDJAkfr6Kb23EsS5/x7v3F7E1Hwnl5nJhRr7Jf5ol\npFyS3gWukCi8p9jbivTs2zv/SmnFW1ecRNvN16XKhd9dFNMt8LzVfnXlgcG4\nmJk/Uzbb9dDo2UcKmf/5zXUWDAFNqv3o/GGO12stL1PjGJneNjQNm8CkeLwd\nb3qNnrSZlfxTuj+bCwEwAlpWmHAw3kh1kk53ut19k9ZOcUuVEL9IClRk7BJ8\n/JEZ\r\n=o4iP\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGanez/tRUSgRWtSorLMWipP7kxMTiCOYkXVSpCwqf83AiEAkfvG3n/r0vngtAs77qBEK83mIkxIdyyZUIR9L3gPAn8="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.1.2_1542771382655_0.8536348691473601"},"_hasShrinkwrap":false},"2.1.3":{"name":"nextein","version":"2.1.3","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"2.1.1","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.2.1","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"3.0.0","pkg-up":"^2.0.0","rehype-parse":"^6.0.0","rehype-raw":"4.0.0","rehype-react":"3.1.0","rehype-stringify":"^5.0.0","remark-parse":"6.0.3","remark-rehype":"4.0.0","unfetch":"^4.0.0","unified":"7.1.0","unist-util-select":"^2.0.0"},"peerDependencies":{"next":"^6.0.0 || ^7.0.0 || ^8.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"10.0.0","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","eslint-config-standard":"12.0.0","hastscript":"5.0.0","jest":"23.2.0","next":"^8.0.0","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"12.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","_id":"nextein@2.1.3","_npmVersion":"6.4.1","_nodeVersion":"10.15.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-m5CtLwpJFiv9eRd3jaiMB2enjetWcUj429mXcGYJsNL9FWAdRWloBqUVOLP4rVjqmjv42pnOyNU9RamLOR3S1w==","shasum":"fb8fd5d416abb9a40d576ad092998e9786f8946a","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.1.3.tgz","fileCount":27,"unpackedSize":76570,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcYyljCRA9TVsSAnZWagAAYwQP/20rnpTpvXPIEOmiafoj\nSJ+i1g4iwiq/oCogAvA6fxwloKdCAy57TLhV9b4IBVsmrEQyIRjsVuwZOJBO\nUjwvidekfAt7ceIWlh/t65QeKqXGVghFCsKrnESUPm19UpTDOLrNQtDhdZt4\nX6j1hNprmfr2xyMi0aaWbP7Xp9YSKr4Ulud4pmvt9xRXji9VEx3BCPA/zzPD\nylRofe1Ujuoykwa9wCNHwFfOBjn6iN7RyNoSX+QFK8ibBsN1HvwreUMnTWEC\nsOk9w99pox6gV+lKXYtOSQA8j+2n4+oxAMXxJHM5lujNtF5iZ2z7VXeInMYb\nB847P5Dn/lcsJ0z++jyALtR5D49XParshHeITfoV/z7pIFUbSaLRZgRe+Gok\nYzIrNk92szYDFEB75Rm5wlCtjTXGnrO86UXYvW6C2jApHpG7A52t8Ry9smnP\nUWTOKTiWYl+gBLs6X1d21W+x5xqmNZ92V1js2sieCEDgcaA/3f/P/7vhJ11e\nRYMRUPemlhtNsR1as3EOPgTxO0kxiwHtUIFTG5KdHoeyArPOAos/CWjQTt0p\n8edVLXmdK2wVYG48uSr6ucBQK6JLCDSZ+2iVR2C8bH8a//Yvyn5GoW0mFtDz\neSoJazcOkiqrcyzCVHlJ8PRlP1sC772TtQ9Ip1oREbNmuITY2VMMyFzxazRg\npeQ3\r\n=bOq8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEGSaa/O12Z6CUb2IKGO7CgbZu2CgZHKO/NmFJv2P+IwAiAUf7vE0gclzJVSsIEqa6TKVgqnJBWaX7627H31rbsK0Q=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.1.3_1550002530626_0.32373520808378387"},"_hasShrinkwrap":false},"2.2.0":{"name":"nextein","version":"2.2.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js' "},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"2.1.2","cross-spawn":"^6.0.0","frontmatter":"0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.2.1","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"3.0.0","pkg-up":"^2.0.0","rehype-parse":"^6.0.0","rehype-raw":"4.0.0","rehype-react":"3.1.0","rehype-stringify":"^5.0.0","remark-parse":"6.0.3","remark-rehype":"4.0.0","unfetch":"^4.0.0","unified":"7.1.0","unist-util-remove-position":"^1.1.2","unist-util-select":"^2.0.0"},"peerDependencies":{"next":"^6.0.0 || ^7.0.0 || ^8.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@taskr/babel":"1.1.0","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-core":"^6.24.1","babel-eslint":"10.0.0","babel-jest":"23.0.1","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-object-rest-spread":"6.26.0","babel-preset-es2015":"^6.24.1","babel-preset-react":"^6.24.1","eslint-config-standard":"12.0.0","hastscript":"5.0.0","jest":"23.2.0","next":"^8.0.0","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"12.0.1","taskr":"1.1.0","taskr-standard":"1.0.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","_id":"nextein@2.2.0","_npmVersion":"6.4.1","_nodeVersion":"10.15.0","_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"dist":{"integrity":"sha512-7xi0fXYs90IKvRsQwztoEaE+tb+18Ch8F5v1fw/jvUg7HTCMvaETrbFZ3Z3SnU5mi08o21N1R7NBTr2qpe8uaQ==","shasum":"e07625a2111ca9529fca8716416097a8d0657ebd","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.2.0.tgz","fileCount":27,"unpackedSize":76233,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcd0I0CRA9TVsSAnZWagAAB2cP/RJVEvp3dOPRgo2DjNVi\na53ekvU5IVMfxyHTu0aG0KPxvkvbi4Gl/pwf5hRTpmxTKZMwZ8MKY9++fjSn\nvt+Btw5k1MUVf8RN7IxTctw6+lE7zo/euikZRh2gVfe0VLAiZ9kL+IS6EVBO\n8HSslTHB3Y5oCVwKQbSm9i24aRPxOpoSGzhuIUWrvbK2xLc2ppGRHQCAR38m\ntthdwPUgS7Oum837GcdT8omch8sOfkK3bMP2ZcypfxjbZ/6H7IaaibNvBMEK\nrx+BPPFTxPpxghsdjEZXpw89/qxc6zomxwcYoWAlxBF/y0MbubdssVqnSisP\nodT9MjK0Kx6Q0TF3HpB+UZaqiagTlTIGpvE1oYHP7lidzlQ4HJbLcEuuV0FQ\nn+zYS8mvQnjKnWR+ptU4qpfDqBeQu/qpi5Uo9FBm1ciBOdSyEfikjCSGSHLu\nTysEFEBmu8+xfKhNf1J06s6t6eGXKcY/g+2ojFlED2gP9TAS+oKfrrvoIXNi\nsOUJsz6aHYPwegVG69x4+iIsZLrF4e9Mkx805UZIz00v56F0K7DzWRZNUQv5\nsu3zxvQR71CI7WKnLkATnmVz2FQGVVQ6ym5rny6nIIvMFPhB3AoLrRST7pzE\nlZt3zibbCKKSu1sttu01y4zACwT4/fwXNOj52r2X6KCjh+QIvD+4YPoyHt8M\npVvg\r\n=eG7N\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC8hrEGs8e2XJ3SqNoBP29qjVIK4l7vfT5md0FR93+HSAiEA69ddOFf3v4Aipa/a/awyWyvN4RgN9VvCH2mMbsEeVok="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.2.0_1551319603614_0.21447531627728234"},"_hasShrinkwrap":false},"2.3.0-beta.0":{"name":"nextein","version":"2.3.0-beta.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"^3.0.2","cross-spawn":"^6.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.2.1","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"^3.0.0","pkg-up":"^3.0.0","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^4.0.1","rehype-stringify":"^6.0.0","remark-parse":"^6.0.3","remark-rehype":"^4.0.1","unfetch":"^4.0.0","unified":"^8.0.1","unist-util-remove-position":"^1.1.2","unist-util-select":"^2.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.4.5","@babel/plugin-proposal-class-properties":"7.4.4","@babel/plugin-proposal-object-rest-spread":"7.4.4","@babel/plugin-transform-runtime":"7.4.4","@babel/preset-env":"7.4.5","@babel/preset-react":"7.0.0","@babel/runtime":"7.4.5","@geut/chan":"^2.0.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^13.0.1","hastscript":"^5.1.0","jest":"^24.8.0","next":"^9.0.0","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^13.0.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/elmasse/nextein.svg)](https://greenkeeper.io/) \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n","readmeFilename":"README.md","_id":"nextein@2.3.0-beta.0","_nodeVersion":"11.12.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-yG/CzSEpCgQ5/gZIQUqgv1gXseYhTNZLh0kA7kA6SwHQzOT2lgznY/q5sITVfZGKalSyRqP/hsIZf6bbGotiCw==","shasum":"d603490feebe82b0d4790a024a04cb5113adf65a","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.3.0-beta.0.tgz","fileCount":28,"unpackedSize":102842,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdLIvHCRA9TVsSAnZWagAAGbIP/1GGrmiFwmkz5aGZI8oM\nmmfc9U4yaKnM1QCc37tPe97n6QJKw8i8aQHxcGhLcG3/8P0zvhni/zkeKxEa\nPPbHUiW03uK2ws7pMoq27h8NO9LAaZXq+PR+fjeMHtTpZ6zKoP9XCTOzTpQ6\n0bntoASO9s26pXnc/04gnv8z5dVJeZR60YinZqPQYnskLGVYUqtm/I9oMhUg\nTA/GjGw14Dgn7HXnTk0WtMHq56obgijS3lHj2ptdW0zcFli9MGzZ7H5kIDA0\nbrig4NzYCMMYFlwc6mTRsfB/EUNZVgEJD91SSnVAWkrby1CsAFStptMoApgv\nNN96tNVzKApUbHztA5VZzQgoKNNkSKDhUdeU/8sLreYoHk04dV0t43sT47LG\nUeyHrm6KnWTUnriUx3TxT/HztA73R/RJeBm+8XAsXjb4eC3rme8eIlCAs/zI\nWbf18vCxlQjL+1+KQHYWJLuPiKFJJ71y07jfV3CDH9HMyoiV59RJPcKMAKM0\njcybLYWTnSNZ+DOs/DsIhHWx+q7u4AnIXBcq14tmCsviRvc5NLzf2I2L0dny\n5BSELc4Uxvp0IoFMI3RyGOwE14DoDW6Tr8XeBTBNyFCXtXsQfL0XvW8ypymH\nq/zG50NvHpS+/3qpaT2IsfG7GatpRJSXzajD4YaE+cxABIBY8B2b77TX1/iq\nEqI1\r\n=cAGV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHaqHgBQT46XKjic37j/MFC6njx/E5wj/yQ6jj04RrY1AiAYZ/enCpAPeGtCb9G+2t3J3gc50R5d7ArskmjDTrAKhg=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.3.0-beta.0_1563200454528_0.9726892687816973"},"_hasShrinkwrap":false},"2.3.0-beta.1":{"name":"nextein","version":"2.3.0-beta.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"^3.0.2","cross-spawn":"^6.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.2.1","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"^3.0.0","pkg-up":"^3.0.0","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^4.0.1","rehype-stringify":"^6.0.0","remark-parse":"^6.0.3","remark-rehype":"^4.0.1","unfetch":"^4.0.0","unified":"^8.0.1","unist-util-remove-position":"^1.1.2","unist-util-select":"^2.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.4.5","@babel/plugin-proposal-class-properties":"7.4.4","@babel/plugin-proposal-object-rest-spread":"7.4.4","@babel/plugin-transform-runtime":"7.4.4","@babel/preset-env":"7.4.5","@babel/preset-react":"7.0.0","@babel/runtime":"7.4.5","@geut/chan":"^2.0.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^13.0.1","hastscript":"^5.1.0","jest":"^24.8.0","next":"^9.0.0","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^13.0.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","_id":"nextein@2.3.0-beta.1","_nodeVersion":"11.12.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-s9odJuIq60rWnf/nudPWkUnW4bDTLOg/JZCD1piDVkiNFBBl1RXEobStqpKuy9gJZNdqv2/N5Q57une9aZi+fg==","shasum":"38be03c52e8a1d6994390906a54e3fbf2e4f4e8c","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.3.0-beta.1.tgz","fileCount":28,"unpackedSize":103070,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdMOBICRA9TVsSAnZWagAAEpkQAI6189V3uun4++MzjeRW\naaz6FLZ2i/fMpNB2ccSt6L/sbDMJR6GxhbnQNw7t9edlA9eDyYG3JlXvfhAO\nDjGCW4joSiamAoLkThaIJkRTBPr0R8X+OoE0OKE9uOOJy8/rzGsQsMnMVNBg\nvjb7wynM+VV2/nvN6Lz2xLXpMMy4rwws8zv5AXo9qIysO/SZTVCMWL9+mGXW\njtPOFnJ0vaMTUJQL3hsQUBngx9v3mNpl9k76QXEPNPjYsfVFICWvoo+jBeQx\ni6JQVCi4JKzvLjn5/C9rW0uL70XE/pyj+RgUO/5djHy2ov92z2XGJUx1kGIN\nmHs/yt4aosg8YN8Dd9Jv/+XhYHeGIb3dTOtgwyxi5LDkAsrPAQlUprfQDv6S\nfw7itVVi3tu77Jj61jnBLqwx2QKeN68zbK/MU22V+7LoY1iUnyjl3QZMdp+A\n53y/gcFFsrm97sVjPFQRrBv+4lNUFavK1fD15ckHscyyjT1qiwYURMAg6BeG\nPjZDRP1ckim6Kn5/G3i1VCoKsR2L1TcLbJYlLMAwo+ELIMd7MxjURKbWS8mx\nB+vVo8K3MVUjcNPC6xEAgXQSRQxqVFbt8VwHSJtEJyBY9y29d8XaCASmXmA2\nX2kAA0NGazKERyzfxUSVMIfgS5hwEQtFKm25pOgY1I5fILGpWym8mvoW9aq9\nQb7X\r\n=AZ5w\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBKPkfgcfpRtxX3m7RJh/Gwaqku/ShxxnyGOdWB3WWvbAiEAg1FATpcY84eBE2ZMdrPKmHjEM0eQ42eHfKHtyLTc0ic="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.3.0-beta.1_1563484230555_0.6882036056629148"},"_hasShrinkwrap":false},"2.3.0":{"name":"nextein","version":"2.3.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"^3.0.2","cross-spawn":"^6.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.2.1","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"^3.0.0","pkg-up":"^3.0.0","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^4.0.1","rehype-stringify":"^6.0.0","remark-parse":"^6.0.3","remark-rehype":"^4.0.1","unfetch":"^4.0.0","unified":"^8.0.1","unist-util-remove-position":"^1.1.2","unist-util-select":"^2.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.5.5","@babel/plugin-proposal-class-properties":"7.5.5","@babel/plugin-proposal-object-rest-spread":"7.5.5","@babel/plugin-transform-runtime":"7.5.5","@babel/preset-env":"7.5.5","@babel/preset-react":"7.0.0","@babel/runtime":"7.5.5","@geut/chan":"^2.0.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^13.0.1","hastscript":"^5.1.0","jest":"^24.8.0","next":"^9.0.0","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^13.0.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","_id":"nextein@2.3.0","_nodeVersion":"11.12.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-H3eX22fuxB/BLLAdv42QzQMD6Ah+pIueoDCioZ5ax+tog6sN1hMif6zjtoLTK3MT//8gaAC70IdRgfEdcQcoog==","shasum":"59cb924e72ecad88c00f58c70a1a970bea9523d2","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.3.0.tgz","fileCount":28,"unpackedSize":108221,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdMRyXCRA9TVsSAnZWagAA1AwP/Rz1OQAoNJ8UzN/2DpHU\nS0qd3h7ASpqrGwkLjB63Wb3+DR3faPf2uJKufdJpnKbjNreZcdT8293IcPGu\n87CaswEb+LB6ma4E/7TBXCaxHcADG/7Vvf93Ni20uE4cjwAq9NMZ2RH/UMeT\nkaWKJEJWestk1tDDJPGcdrVGiyCiHGe9mukEAW0EHIAeqG5otvsajnf6KdVj\nrx8/KzK8Ttm7BgrH7bY2y21CpyP44ywzKitzx9Tyg/w2GVDXdbQaIfhN4Ak/\nk8ErcaRRTcQiGf+Uy7sXdQvbkSL2absdCYlaqv0Oc2EDGytNLYDg8Wa0SuqE\nN8yjVZ1vDDhyZ8VKhC6Q1SfyYqbvOnzHpN01IzxQuwDdwUdEId5A/lFpm4ay\nfKu7eBbIxccD5z1RNa55eA1BRrctUb0GldClDt7hjy+/lOhgRLj8TjCLm1nu\n/+7rqdfcNBTpDHhQMuEORh4tR44hPzKL99RDN8BxYOT3JBhnW8bSWVX1c+51\n3FCNSyKxwIOMDs4jokaEOc9IUi8q/Mi0nMZl71uAvN3HD6YiDlCupQs4HrXA\nGAyFC++q0pp2f+nDYy1zHS0sf1B39MYlzPpibPjDR0fc1WV8Tvhdga8nT9i6\neZBG47ZfUTfLBUKCDZcDWpA2SBjKt2VtL0pQglkIypiWEFogJL95qj7+xu/r\nbpKK\r\n=Ycx+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID8bcuuq46hTMStFPupskLUKMENYl4EhDw9huMoKwJTMAiAaV2eJt1UG0HqtNnTm0z//uZAdyJpBxu08gXqk2n8N8w=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.3.0_1563499670525_0.9670553015746948"},"_hasShrinkwrap":false},"2.3.1":{"name":"nextein","version":"2.3.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"^3.1.1","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.2.1","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.2","path-match":"^1.2.4","path-to-regexp":"^3.0.0","pkg-up":"^3.0.0","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^4.0.1","rehype-stringify":"^6.0.0","remark-parse":"^7.0.0","remark-rehype":"^5.0.0","unfetch":"^4.0.0","unified":"^8.4.0","unist-util-remove-position":"^1.1.2","unist-util-select":"^2.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.6.4","@babel/plugin-proposal-class-properties":"7.5.5","@babel/plugin-proposal-object-rest-spread":"7.6.2","@babel/plugin-transform-runtime":"7.6.2","@babel/preset-env":"7.6.3","@babel/preset-react":"7.6.3","@babel/runtime":"7.6.3","@geut/chan":"^2.1.1","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^9.0.0","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"_id":"nextein@2.3.1","_nodeVersion":"11.12.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-2Vhjiq27dHB4QsbpIY643Wsi4twaKcpqLk8sOKzBQzEV8MsS8znT3VCS6SXo4VgFlg+pJsHXfVtSdNd280h8Lg==","shasum":"9a97ec4f24b1ce636207ccb9bc91b656b4492d0c","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.3.1.tgz","fileCount":28,"unpackedSize":112208,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdod9ZCRA9TVsSAnZWagAA6OUQAKLORDCqugRX854bqbCJ\nFBmCgE+Hs+YlffCMtY7pDuV96YAFxkpCYqw/tSsuJfYdtiZhWAMFn+BmN1bh\nw5om7GByGYAnYsnrwfRjl+l0JaGEMPiG3Ct2dPQKII0PjJT694JUmU/jcyb/\n7sdVyyTnFN/v3Lz0TMa73DbbaYeUrKTepG/F308hcTS5oFP8Izmv+nH56VlC\nzfjRpXU519aJxdqvER0FioKbnmucRnu/FNX6B2r8ZLlbEcArx3EMSUk0gIl2\nZe0eDEs8ga0QKECEMAdIDx0eG5Mgv54n7f78bIhJAh9he936PtkBWnDG93ld\nIZQTT++0skZXqA7i5VFgifCsShPvSOsOAdOqXfa9f5QRuFqnl1EPdsbH9YCQ\n3NRo8bEGfN0kBtB2OmbdLGaOy/H5xLEEQUCSrOAkt8OAjDYWV4xLGAmZvzoL\n+uoIeAQGzs1ztdpdlqg4N9KSuUlw8yt49hunmyA1TOGydmenHZVPnMynaMrb\nNreOHjQ+QQFUNLAE0O6MmTPbsUCnzjy0PKk/XW4TZnA0LQzejpPqr59czS/I\ndKq6g5Kmc/46Munv7RG1B7CrhpbXnm2wyCJrJ7j8jmyYeISIyG1GKd18BQLF\nAJ+yWP0CMeDePiXBQxzP3GzMaZl5ZrHTszqtjEHiqSatwunS38gTjBUB7E6g\njH4P\r\n=a8Cz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCKrIc4MgG3xlZgElyiJ4wzn4YDxEOIIJlwQC+DQ0REEgIhAKZl6nZcMgzQyhUQGGfw1xkwy9L71R3le9scEfloeQf+"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.3.1_1570889560589_0.25011965644766554"},"_hasShrinkwrap":false},"2.3.2":{"name":"nextein","version":"2.3.2","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"^3.3.1","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.1","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.2","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^4.0.1","rehype-stringify":"^6.0.0","remark-parse":"^7.0.0","remark-rehype":"^5.0.0","unfetch":"^4.0.0","unified":"^8.4.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.7.7","@babel/plugin-proposal-class-properties":"7.7.4","@babel/plugin-proposal-object-rest-spread":"7.7.7","@babel/plugin-transform-runtime":"7.7.6","@babel/preset-env":"7.7.7","@babel/preset-react":"7.7.4","@babel/runtime":"7.7.7","@geut/chan":"^2.1.1","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^9.0.0","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"gitHead":"bb6a6965e43fe88628d68852553d35955bd79fa9","_id":"nextein@2.3.2","_nodeVersion":"11.12.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-JZhugia3EtFJNzY7mmZ9Yo4GjnXNWRulXn2gK9Dfy74Q0tqKcBAJT5Y6Bm7G9tlRm9+GSqOCiUuaW3UCxPK0mA==","shasum":"aca2c3421b47ec4b65c238051e2adc3efdf4e75d","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.3.2.tgz","fileCount":29,"unpackedSize":112823,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeALpLCRA9TVsSAnZWagAAur4P/jD9k+9ky56uc2Awj1rM\ngV2s8vhlEEZvXUrX8RHkql3tOdSefpLI1F8WDwxwzS22r8gjZLrmc82yosy1\nrHAZFWRP8v1SIOLiM6dEM61Anh9tk45UqLMr2cw1euE4tvDFDlETxepNipXt\n7ljLZRX00Dmw+i0zNeFtohIL9VwqJPdP1My8wUXy0EOoftxUqejz7Iyzkd70\n63ZzRRkpOtLyDUyR9uuen6NWDUzq6cfowxQXNqjoR/Anc+ywEt0yJJuOHqzu\n1ODH5OjJtfjOOBVQkkPFpI5pZJe3uOVo9nFmZExdaOh6PmR0LDndVvRiC91b\ncnpyHpLcDLmTCB1QyA4duFirIVQ7oyTqjx+yc1eoeYD7x9QKurUnVHXp8f/Z\nCLkPzIc9mjWlvxL+TOLwQCcNfIuP5mdKoVF4XfQyzt6k/iRVz/QsEmQonreh\nzR8Nyvz0FNWKS99UK/JTX3Zk60/tHAHuyMqP4w2FkovEnVOVnSYYQsrPDFhm\nM5pp2UE9u8IeJ6lJJCLTN9sbsAeeGobQI6mGH2DioaUNbBSAxjypbC8xdyii\nmLQazW8ulYaV875x9mFG/1Zxh5LzUOS6YQfOQ59N+ZPIj6NiH7URrK3+YISF\nrGLSy4LMbyQKC9Yo+F3ZS2c7joY6cu9Xa+h8hjMj1YgBVsRv1CtybnmnFvAh\nmhYw\r\n=lNi1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDJyJv4odeRTTmzX5+IjbziOWlU58En3zZ2FKKgYQnguwIhAPhpAaAn773jnvzGoiPLJUAQqy6Ok+fYeqONOGgTVvK+"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.3.2_1577105994921_0.8827069080280567"},"_hasShrinkwrap":false},"2.3.3":{"name":"nextein","version":"2.3.3","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"./dist/bin/nextein"},"dependencies":{"chokidar":"^3.3.1","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.1","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.2","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^4.0.1","rehype-stringify":"^6.0.0","remark-parse":"^7.0.0","remark-rehype":"^5.0.0","unfetch":"^4.0.0","unified":"^8.4.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.7.7","@babel/plugin-proposal-class-properties":"7.7.4","@babel/plugin-proposal-object-rest-spread":"7.7.7","@babel/plugin-transform-runtime":"7.7.6","@babel/preset-env":"7.7.7","@babel/preset-react":"7.7.4","@babel/runtime":"7.7.7","@geut/chan":"^2.1.1","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^9.0.0","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"gitHead":"b9a9b04e080b8966f5be154c28772b14a889f833","_id":"nextein@2.3.3","_nodeVersion":"11.12.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-FxG1WRyQQf3Og17vNfTam1ihG0mQNcKANoXFT8sArBRqxdJmws7qF/+vM6ka2BSurKvrpBk/TsO4gGLYIXiEYw==","shasum":"7a2577c89357a12648b775a89d062fe77290eb3a","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.3.3.tgz","fileCount":29,"unpackedSize":112939,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeBmRnCRA9TVsSAnZWagAAHQgP/3ZjwoEWdQ+DaururkaT\n3EixeWwOqKp+kJraC3gPjcgVeh4EMPugiyH9GLvF40rebL3VuVtOJ2ArHOmp\nr+w8/2uku8ZwTVucM1GG8jZM1J3mLOBxu55fzp9/5zgYLh1wDD1QUIIGxV3J\nsNT7B8rFT939Wly2nYVoVM+C/ZlY40nUCXOjpnyLnu+ZA+SOk1CGgKdEH3K6\nt4qtCDlqRgeK0B/ExM0J/eN4BCt65X0BfvPVKOuGPti1aWlK3B2/rx+XOy3c\nDw9/Xr0UFJf0i/ekBxH9fXG0HZOEO8RcaM9cKmmAK6+GQbEdkNmKnWhDMkUD\nEJMXbDb0u0jeyAzWJUYSFueNrPNXFe4dxOaIoA2c9QU4unlx8SRisy1dSP3V\nqHbvFmT99PS46GGL/d1AIHK/zO3Br1wyMFYTJlRDs+S+ocarlRUCIuOFGgFo\n41YDKl81EuqHxBN85B7Ot6NBu2/wH9tFqkX2dv0Frux+ZaFAR9hyEzaSIx0a\nmYJQXXnuaayXckKLwzj1MxdC9T8qsbtbBFdss4pAx3WpQ96YhR0YO+ZF4wob\nIN4Vcizb7DGBah9sqNEMFsY0Gqlemz43MwebRBU4rgC/ffckGkUwaqCMQq0H\nlI/Xrtivmj4D8YyJ+iYNXxUu0KCOPSYJ40ZZk7uijMD3A6zdeQGD08LOBdvV\n3z8c\r\n=DiLb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAiqFXm+4+DEkJ3d+V+uSIsP0l+5RTPCdhORGaqCrSQ/AiAilyZEqtOSg9b0gYPAbqs3dCn4ZQ8uACdYc3Mfs/+yPg=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.3.3_1577477223139_0.002343168649092897"},"_hasShrinkwrap":false},"2.3.4":{"name":"nextein","version":"2.3.4","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.3.1","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.2","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"^8.0.0","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"^2.1.1","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^9.3.4","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"gitHead":"0b246ddbdc071f977c29d714d533614c4496b5d1","_id":"nextein@2.3.4","_nodeVersion":"12.16.1","_npmVersion":"6.14.1","dist":{"integrity":"sha512-VqtoIjWHal5IjCNQzIbhFP9j9Szv/aBjyFy26vJqx7QzVVG9wbrx6nJnUDTjQROUY1SjP9fUkHgKMbTDWhUGSA==","shasum":"6b80133734825ecb47eb409aed0532bbe4e817e7","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.3.4.tgz","fileCount":29,"unpackedSize":117322,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJei1CaCRA9TVsSAnZWagAAsO0P/jeVHA9C6XHNXOjo04JQ\nUy1OSg2QJz0jutSN8e9p8fuj4c3qtOHUMGuUrzpZR1lQ2u60XMEWQQ/Ij45Q\nHjq4MWsp8t4Ebo1Ix8fjWWCoi1oy154JSl/B8LAYNiM9jnB+6iIBIKC5WWel\n9z2NKJfVM6leEh/jgulBCp5MbpDubAlqQTKdv2NwTZ9F6Lr5vUUVkIukI+Ok\nc8vkKPrGT7/z12CXxlLuYsOfrce27b3FH0Objs4uleSA7ocFk0ZnUZfW2gde\nph6/mT+riqiwGpMLZdkCe57SrA38mXnhQGthAi7I3rn2oJgm5/cTO85NnGqQ\nM1jw9RkMbrFQSg6dfoGvk1sxZ4xu/37i5Hzc2GXrHQwkLSy8Wr7XMqFKwBqe\n15vwI2udTNC1BLd4PJbaWf2M8LXSDvDkmXExLMkilLdmuAtiOYtZ2mMIu/J+\naJIt3A9fV9nke8I4CfhXYKElwZZWnIbP8hMGKOBANWCyDirS1wfi/M4dTOBr\nDr/yd6tWs8RUgCmTXjJcc+pQkX1iKN37wKHp5efhJ2eowJdVIhq32TAh2+0r\nazEhAs2bC4scmhyb/WOZiZStRG49nQx2rgesyCHZXHzrYRBIKn1jSPyd6ZSr\nWxStCihtf8wCejuISRXMhmSi7f4248l5+JAphsFlYSWNkHfqkskcwMK5mCzI\nvvw4\r\n=S2a3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDU16Lksnx0g5Tu32nDdftFuURrJpW42NuS6CiBRFOQDAIhAOtozmONbXCinLEIFvVqYAV3k7/1qwcm4wedggKmFw/F"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.3.4_1586188441562_0.15905335407660837"},"_hasShrinkwrap":false},"2.4.0-beta.0":{"name":"nextein","version":"2.4.0-beta.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.3.1","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.2","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"^8.0.0","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"^2.1.1","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^9.3.4","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"e5f8ffb46f646373f5c5f7138fdccec5f560bdf8","_id":"nextein@2.4.0-beta.0","_nodeVersion":"12.16.1","_npmVersion":"6.14.1","dist":{"integrity":"sha512-xs/t0aH2HDtNOQmEWzoJjiVN/T6Tb41fg652Yv0eWkyxo8nU5IWKekWP8qs7mBXav2wygxE2TIY2xwuUuhUU4w==","shasum":"fba803a8ce50e7ca2d1119983ee703128695e405","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.4.0-beta.0.tgz","fileCount":29,"unpackedSize":116776,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJejx4iCRA9TVsSAnZWagAAqAYQAI0h+p+IDxuyEj0j11rD\nW2aaHz7nyxmX7pESOYLPPiXWyzQ++Drv6WZj1nG/9VqZ0MsUQ86MQe1LfY9x\nOV8DudG1leSYAX8y+TMoiT9YeahpbJm1vJwvFr8FXWEScSFA2zTt226N7TuK\nyayVQXwHDTmJyCc5K9Dwodn2ps5s0uQv4giSdH1id1IIeLng98kTih9b6Kct\nfOIwI0+JcwUE9ctPJvkMlHhdBCymOK8tHHCSbiXl+PzhZEf1GISsn/G81A87\nEMBkqoF+lNuxM7/hl1aYHl1UMaWuE5lfxekprGgmt+DU5uvi3bFYBTnmbUfc\n9uHIbykXjKbrxgJMMuuWh5mq5jg2ZDsmp7iUQYqeJ5atsmHaDSPsCONiR7lX\niOsMYuKPi6dAqsCAPj/HkLFtsu4JPzblikPNsXbhSlvH4u/cANKsNynlYU1O\n9kzTV+nEFksArBH+njgibi28ILGYVwalGSaDo5AlC++HEftE4j6YpQ9sYDy9\nfPTuf8zO/s9dPxWbQs1SJG4x6HjPEHHpglo5rdC2DMBTZOQQHdOPeKFHTbtp\nCef/Nk4EP4H7mYZ1bpUL2iu7LqUt6SUcmiZlqEvfNhec7Lshx3R32nuCBIiu\n0uJptnqZj8Jw2oHG1Or6UhexiYXnXz72MUcX4eOQb/ATH4wyapL4C+J1xyhP\nsSXx\r\n=3/iH\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCD9VGs9GoaWI74Q0Im3yRUobylMxYzZ8Iy9JHsWgQLKwIhALBQFjos/XVaYnhfD/hw6S5TCWpGyOO1InjlgmyoVQJ6"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.4.0-beta.0_1586437665877_0.432495202118125"},"_hasShrinkwrap":false},"2.4.0":{"name":"nextein","version":"2.4.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.3.1","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.2","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"^8.0.0","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"^2.1.1","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^9.3.4","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"gitHead":"7c35c12c2b47840e698d6cca30e407fe5a2dffb1","_id":"nextein@2.4.0","_nodeVersion":"12.16.1","_npmVersion":"6.14.1","dist":{"integrity":"sha512-gQdbU2q3SOoLYGIGaeaiMV6sYCLz8QpZQ9/cAMEuaEr63HfpXm5IY29zFTIFKsgHT0zxqJP14hDoaxZkKzy7pw==","shasum":"c12d869c69ea471df76f5eaaf2dcb6cd0f698705","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.4.0.tgz","fileCount":29,"unpackedSize":116569,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJek2q6CRA9TVsSAnZWagAAU0sP/iyz9nshnONpjuPckmWa\nDKCmH0zi6/jc0qFlWrCWw1fMRE+4heRYy4bdCGmP9dMmLfsSOZ24W119WbfL\nfua5Z6DU3EvyCwOPfPQbmCOXejnOY67qXIqeCM5Vg/Ox4O2hgVK9KUWGmPwG\nYAe1sjr3M9kd7EeYN9X9Lk6I7n6w5gwz3/ZTVgwSclchYAqOiRtJjUcRZ1um\n6vIaJSpvf+yMmtgWjMuB3EBaRHQ3lkbh1inU5ZczSrU86AHXFsh0p/doSElf\nF4uDXl4exYg/Tni14vffOX1kDtjO16p6ILptBdr1bcwS1o8NjgTiidfPyPQD\n0OI6IWCjqAybcoqLQeOLm5H73qQB279BkCNIH6xid56jFyS+OIny0RCD950z\nuZq6f6w3xB20PGXiQ1XoOBJChxuTAAqLC0bmPF6hYYxUYx3ziRVmYP4tJtjT\n77kD+GOihEEniU3Nq/J/XqlNApjjc19LAo7Pphm6kFyPrBgMygQLSwbDZjcP\n/2HR6GLFvvr3qKLWRrCHSqp3v9mcbaCXFGHAAb16VHlqIibmVt37j5GVwtVT\nZSGat5lwKLbgswMfmz2y42Xs2Z3ukhujQOuymn6fvjIl6Z2ldWQO+zXLGHcD\nAVpxHwzy7mrx3aivEPx6L3C9rYA5pIDLG9NRmmAwjRphJi+2p9fsNi6lYeGt\nGmSO\r\n=d/ES\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDEQEvMjj2ff7S5T5nr+oK86i+zhAKtZgmCy7wn1dUFIQIgD0TVvguyj6m4sZkrapmjHL2/iYnlqf1VLTn3Iq+8+zc="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.4.0_1586719417693_0.4469391479954048"},"_hasShrinkwrap":false},"2.4.1-beta.0":{"name":"nextein","version":"2.4.1-beta.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.3.1","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.2","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"^8.0.0","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"^2.1.1","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^9.3.4","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"fe2dcb1601c448e60aea29a9c23b3b3b45290a50","_id":"nextein@2.4.1-beta.0","_nodeVersion":"12.16.1","_npmVersion":"6.14.1","dist":{"integrity":"sha512-QBd/Pqm+d3/JcWi0sYmDmKG3/F0W4XFY5J1mXdhDUzPVHfSYfV6QsxhmC3ubjvivTqiTkNrCCZ0FMI+XRaxcUA==","shasum":"87dac89307a9d766aa918e01ac3cb7238b0baccc","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.4.1-beta.0.tgz","fileCount":29,"unpackedSize":116597,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJepz7ACRA9TVsSAnZWagAAItUP/AnfOjdEQKjZG6Prf3HH\nCUEOmNkM77uQjXVWMbZjuvkYNYm6WkpsBMAXlMQk63ws+DRjB0wWtBjHFRRK\nfPxz5Z4LItYW1e2sbwkN445TCEIPRPdm/KnvSJW8fMtmbkSep+scila46BGV\nMTgLrtOtckGSrsKnVUlYoI1lRPRlDUEo9OylyTe4GONoUkZ7HZamkBm8E08t\nPMqB9nEUqB1JpDd6hHarLzW0yuoKvjHnw7Vdin5+h9njDs5dLe1I7kpIvhZc\nxTtEd0i9YxsY291TZi+FAUDvhIq2OLYm3/plfjRMou/3mYnwfGbJ2209kEjZ\n2KpUr2bc8rCeAO8Eb9Nd+YZkKBLwvOcjx0cBW8GFUrAz7fjvP60ikdtcwFIP\noUpVIiaVlFp4b6X2k1W0CWdkBZ1NVWjvb/0vPdsbadOfWKzOhtvZ0PfO8616\ndFqs2iI/okQtKF0yI5d2+CKn2YbwLnGfbuTgTc3YE/xOWI8CLXFOkvM7v+NF\nYWhq++f6BFfvLF+VDN8L9Phrvx9kRl0qiCQYZeiDccKGTewWZvfkSAGvveWI\nEibx2GDHe9SkM8EbgdxPSTmYsdEuYvg2zZYeFMdwqeO6Shz2MixB9mjMebne\noKcMeG90UOI5a2AkW245YJkvfpi7DMbJ4D5SI2QRF6mZbO4MsvE++LdIkgaG\nJ6gW\r\n=mEm8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCjBp0kj4I1CAbvBazG4u+Do4kY/FFvmZ83rLdH+6wfawIhANdaibAbqK5nDugjU3cZq3XmQxlZnKp429anDb5leNwH"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.4.1-beta.0_1588018879487_0.057448863571178066"},"_hasShrinkwrap":false},"2.4.1":{"name":"nextein","version":"2.4.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.3.1","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.2","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"^8.0.0","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"^2.1.1","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^9.3.4","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"gitHead":"366ed2bef40df21b9c6567c60e82a18329b56258","_id":"nextein@2.4.1","_nodeVersion":"12.16.1","_npmVersion":"6.14.1","dist":{"integrity":"sha512-gFLN7tnchC6g7fjGm/V7K02ejrhEdfhiO6pNLzfBZ7SgL4mxG7MQJdkrzb1/83CAEZQRuUYCYBqsDDQXhyFjAg==","shasum":"1790d6001742fcf83abeec7fe5b7c471ee9784de","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.4.1.tgz","fileCount":29,"unpackedSize":116770,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJep0KcCRA9TVsSAnZWagAAouYQAIdxwg4bWv/5AeFLOS5m\nui1VzicbPA+xFBKsimZxfgAghwFjQtsxRIATm3s/j/CcP+C+d8XOuQ/T8fBw\nAKJ5QK+cbEssQhWLM3OqHc9d0SfSsVDbOWCIUfvVppsWxoAdS1Uhlu4NALfV\n2/7fUcuIq9oYlFg5tO5R8kw0o0VPF5pzBsE41k2h6WcpXkWCgtGjk2z9958F\ncJ5GshDp6XlHkfo2PUK8jrLjBB8/KwakCHtTGMUSyV2M5iMaeOZZmYrpxW/r\nFW0/3rXLKBmhaQC/H0hHZUnhcshB4ms+5LNc2X3U39Y7JtW1yOrfq8TV/LJh\n5+6m0aoNfva/10k/lVNJ1KEVXnDiYixbCasx3D4wGdX5nEmLyLYSI9BAZ1pb\nRrW8QRi01PMqhu4U9KogbEYNESQNEBHPKxWhjZ4hD/UabtdWPhwpiRM5zuHX\n/gJxaIlI5Vy8P2Sf4GVmOycyfYXRiTlYVhEwknBNayMliMrqD58vXA7suHVo\nq2NJEXKLnLfbqeGXRjFr3TdsVqJ5LqjZ59GJRqUy9/yX/saSa++UWCvJK9WW\ncHmWtNVEnO/PClvmUKkjnZp/rPGKV4hApY/iMXLYlca85JrtS6xrScMEt8VP\ndy2EAC/3FXThhHh8vMU6mcVO8WPWZ2Nv1i5MKwa+EMeUwkCCKF9H9A6lLdpz\nYvYW\r\n=Q5HC\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGpaM34cPiGMnDNu1Zz2sDCBRy+yZiukLatLwrSUm4ZlAiEA5yz8LrZm8SY/ZNgPI5ONxlftke5TCrz3mQmKlCeiRdE="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.4.1_1588019867682_0.5596590998548263"},"_hasShrinkwrap":false},"2.5.0-beta.0":{"name":"nextein","version":"2.5.0-beta.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"3.4.0","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.2","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"ed3fb5eb8893269b41720326fc4147b07b0db43c","_id":"nextein@2.5.0-beta.0","_nodeVersion":"12.16.1","_npmVersion":"6.14.1","dist":{"integrity":"sha512-TTWXc43BPDP03rxRHHCN3zOb/SJR7eKM/vQ+5ow+4wl51GU5ilezcui5g2H7kr3ENPiBRqVMcEzlPYsB5agK4Q==","shasum":"1239a148d9018691c22457ee723b6749b0f7b4b4","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.5.0-beta.0.tgz","fileCount":29,"unpackedSize":117964,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJerysoCRA9TVsSAnZWagAAOh8P/03OlQwmpd6c1la9PFoI\nio7ooZ/GxWGrzrPuLm7NuodNcj3//4CcisbpWkw5P32hsFodI5wFeY9oPHrV\n86lNkF2b7oRbeazZmQW7dSSMCm85miMo/AJS/4KgFBjw7Y72sy54DwoGRKls\nESs1TerBAH2qRYYpwUQR+WRFS03pAwqXpCMDJrfXf2TdmxinBHN97uWLuU4Z\nHjv5FYD4d75pnDQ6lZZZrCDhLZGLwxRFZzT7PNUXdyTKXke4hl9/S/qGBXho\nDhAvwgCa7hU0Vt2JABfri6jKTnOeUcSF1HeAEmJnyW4spAUkMELcgYExYTs8\niyIcYo1bTkKpna9w26n7rxpUVorWRdNucgSKbAvDd66r3EMv/7tiEWRlHCXB\nIcpgLul0fPNYj8YN8tQO8Ki3jRfET7PoSUEUfMbi5CcgCalRnzcxOhpD+rJd\n/UdqjUf2taEg7hYs/RIj3OhWhJmBvIk1+4nYct06HVmlCn0GailF/rzJwIsL\nbGAHQ8yffg1hzd9yMWhbeKr3hl99WPJjGnf9iN93M6oFvZWpEYHCfhct3dyn\nz7zB9nDRqmuXeYpSFX6q7ntS6srnpScl+N6Zvlu3gHL4BoEgbLJuI8cew6vO\nWDg66Z6kxcSV0a2C0WOFXLuhHdMwkV0OljaaXzczqhuvidTtyqXyaMV1wIBp\nJA+G\r\n=VI/c\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCf/ctCy8zCRfzZtz5+jns7tZMqdlq4XPOkbJjRqkGBUAIhAJTAGfim6AzlbefOjqe6HS5rR0RnUvDxFoq1fLDSYVoy"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.5.0-beta.0_1588538151588_0.9658810698288574"},"_hasShrinkwrap":false},"2.5.0":{"name":"nextein","version":"2.5.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"3.4.0","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.2","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"gitHead":"6c525969ff0cd194f5d37f94e841831950ae97b5","_id":"nextein@2.5.0","_nodeVersion":"12.16.1","_npmVersion":"6.14.1","dist":{"integrity":"sha512-wPHgwL+XCA0HQiVKS6iqsJrTodB45KEhXK7CHJU9F9f0ZWUBiQYhdQ27s73QyhNIWKhlFdop3TQH7k3rMuFKFQ==","shasum":"3ab511e3fbedd68328424835f0e02453d1cf08fe","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.5.0.tgz","fileCount":29,"unpackedSize":118050,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJescE3CRA9TVsSAnZWagAAv4AP/iaqRmL/hb3e5bmegZbK\nqx9Pvpp/b7Wg4esot8hOmF1n53/riDrHopu2nf/Hya8XIcFAYWPQSn+FNlwk\n1WBIKnme5diW2kMcIjV35oQ0mOLusfzQpOpo5PRMNFcWsaUbLWzozR4deMDX\n065ejVULkCuSLYLCY2k0hD/a7KqYa9Yh3Zwr6VGvF8zaSBWoj+mUBA68Srnn\naOSqxZZgf/nBydUPw5G8fQYqj+SDfuFu3Hhx3KroGCcdcHiARSdASAP2T6u9\nAnOerdwpY4lRyL7/Hir/GIOJliHJgBMTg661YHz+ZyXD+4j8UEXhQ/H6eu4z\n7g8+EB7Jf9IJ3SkGMVFDLk3oCLFusUgmlGpHZuJcFpcVTOwuM3W+M2ZKjVls\n42vqK/hHJVBCYhiOg1jFejywll5Ehi471Ey8GSt9HON+bNWO2rGLPWb9KdnP\n7x+/F+bt/q/Kom0uZZfsQc7tC4HsnqTPGzInkcqwj5D5aJ4I9vM8hqhYVFvy\ncSXaBmpXHCfPCJoi4yMpigK+KolOYlgtIq3vtgJBNVihapSUAOlLFFaUTHFV\nav03tEVLZ0XBSrJMoBzvdnam62Fh3GJlt6Rx6BTUMKxFOTSRqgAigu2j4M3r\nSS1elp4Z2me6ndJJsVzR559d5BUzm+60ZAxMEdpMvpMrIluxoYgwJEqQaU9N\nWRA7\r\n=4LL9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICT1jsclqO6mEeZNOypMl45lKPPW+MWrb8Y0YPg/TPBfAiEAvzszwHsFMhdrGKj9grqpxtitgE/y5mH+hfHbT9U7hSo="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.5.0_1588707639052_0.6628410222451147"},"_hasShrinkwrap":false},"2.5.1":{"name":"nextein","version":"2.5.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"3.4.0","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.2","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"gitHead":"6c0a08887735621fb33a7ac87330ae7a37c65bb5","_id":"nextein@2.5.1","_nodeVersion":"12.16.1","_npmVersion":"6.14.1","dist":{"integrity":"sha512-BmWl15g7+pjqoyXAqEX2+vZ4YIfaY9A2r3oybIWsVqbsUAss0W3H0Tm/HENnc0gLVRk0pIFOI3+E1c+Yq1H7SA==","shasum":"d18e2c1015dcbca5e24a44863015ef45592a4e72","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.5.1.tgz","fileCount":29,"unpackedSize":118203,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeuU1XCRA9TVsSAnZWagAAN4QQAJhdLrI0U74SYP7PRzzF\nF9YetZJ/bMiqzSghw0Gr9mKhVvbMCwxk2oA3riAykC1T66v9TUOy8baqVtGW\nawQgrf3eb37kjfQp+3Ny5fgxn/gTYxxlWJ/hi+bhUhbdRsvoi/YWDIbP6XF0\n2aoGzDdczzp+uGOIcmKcqbE1yUd+0Oubg/6mUQdW/4erYspz2pYhuR+bx1yj\noX7SognRVGVBChRNOTryNjYEpfanAYws10WNCIEb7v+uPuItvlCXdB4JjUTs\nXOqsO5ZgJL3p8a8i3R6krd1vf7OyOnwEmQyQ96KOJyq/tFqC84lQky7oXEzv\nCEgJ+NpoPTUWGqZnvfrFzxC9+HRt+6vdKw8IiJSY3sRVcf/+/IM1MHODKP1v\nDRAFc9jnm0Fbi/0nbDUSKQ42AwXNy7rFqEQizVbYyAua8kpbe5khpYhcQW1x\nuwhdmdb85eOmHCCg1h8CQ3jCae5yDeF27foDwGKC7MjPYinLnFS/+aCssCbn\nlLB+8Jmrs6DqjuHjXt86x1dznCFSODsOVEd14vs/EDOa7MmgObJD0CUJjsPT\n2tIc6U6sk7QIdbUknkQfWzrLGgh/aJJ87KZDHIlZ33ClIGtbfhgmn+7qCoA1\ngNtrCzufysG3CDpgrlpTDSWfXucpwnYQ4HAc2zw4BlQOEt21NvzyF2koDPSf\noEmU\r\n=mFSS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCtKaC4i1+HOoJpECTu3WQX751O8YF1kx/q9G4yeFg/TQIgGpKTHifUCBJaEC2Jzz4ALKGFk4gT8hoouGSP8APXHyM="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.5.1_1589202262604_0.7872337152015141"},"_hasShrinkwrap":false},"2.6.0-beta.0":{"name":"nextein","version":"2.6.0-beta.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"3.4.0","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"2bdb69e467d4e994136adec159afdbc85d5aca4a","_id":"nextein@2.6.0-beta.0","_nodeVersion":"12.16.1","_npmVersion":"6.14.1","dist":{"integrity":"sha512-a3rBCYZNfNnkfeSZNkex3DeJpeReHzqXU1DKP4I/PwBys6fSH2uoR+qYMg/cUsbVCGRj1kmUN4pD2aB5FnYW3g==","shasum":"fba8bfbd56eeeea642fedf66c89e3725c3efe11f","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.6.0-beta.0.tgz","fileCount":30,"unpackedSize":119420,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfEfO8CRA9TVsSAnZWagAAi/8QAJjMRgq0EFqulut6CQFl\n/JUGLrIraa9O9eoh9ltpTR3BEHzRO8+AV3p6SaLfv13rrK+OBj9c2Yv9iUdd\nXvsdiQSIpVy5fYPGKtCfBGGvW9VtXJJMU4xTlaUPYuY1ZMUG5CPJU0kjMRyk\n2r9l/5FPrv56hJccJ/3ETInnpqYmjiLsF2EZ/HKcAZUhjUIq/qChO3ZNDGCw\nlJvSOiz7FfVvrCwRlRYxs4VDoBjFD4W3v32mUMbHPAcOYx85YagA5L3hTXRQ\nBHBlQC0t+sbLHIxCROkMc6jx2Cd9xEbFkJS/s1N4WR7avWoRei+zPqbceMBp\nVrtxg3G2nXvgcq0DCOkgRZ/bW0kQRgGImIxKaCyl7yrKDiqbDVUMcG9iVTZ9\n95nKNIU02H43sBpDRzF38HkBlc589b8vvgeiX1ykL+Z3zkRTliHgRMRLq+3d\nTLpPeWOjbjEyKMWZmbdWzLqSoosV9pT+qeJWPBgHXaeDXMDblJHA/uBkgneR\nc8fpg9aa9PDbjwUCiv5+ba+kHzLe6LVktcF6wI0OLmGiMvfV0xVzVITiImQ9\nOHmxDXTJKSQizgjpG+nlaNdgxXX5mtYhpamQKfk6Ld2aKTiEafWeCkgtOgCm\no/blnVzem7jUPeFnF/9sQl3a+6BciuLJmZZqv1TGDNkm2arLuRoCUjOGkmyR\nN2vk\r\n=YjaY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE+WnrakZBMYBljKV4qm5Qtr95LW7js306c0wGxoghlsAiA/wuvc2C0W2d2Xl5+Fl3isfOUhQbzcHzSQOXIthHN70A=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.6.0-beta.0_1595012027675_0.06049127733364723"},"_hasShrinkwrap":false},"2.6.0-beta.1":{"name":"nextein","version":"2.6.0-beta.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"3.4.0","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"bc88a70eca71b2fee8ecdd422202d5805ea7e749","_id":"nextein@2.6.0-beta.1","_nodeVersion":"12.16.1","_npmVersion":"6.14.1","dist":{"integrity":"sha512-lf9eMG5uCcERmg6eQtgsealnmAVrod5haaO1dJcYOyZD10Dtw8AXYdi73xr4TtW7R+whfRKDA8YCKBKT1qh/Gg==","shasum":"760f7f6743e27a5826ae891824ccd3ba656407d6","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.6.0-beta.1.tgz","fileCount":30,"unpackedSize":122111,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfEfV/CRA9TVsSAnZWagAAyOcQAI87mg7ganMdj8SWpI+/\niYtjFSj/aZZO7mp6XYBibn54XFUeB6pwIJwir2+kQzO52clnGCMRUt85nf3a\nYWrVPcSRNoeBgRxRodj3VfIldDrpxDS453tx1ZQNdkr6Qv0Zfh2h55PusQJD\nryAC9IKcRQKgcJbEQLcQ0091IEdJU232rbh3Y3xyP68fpfNvrBWjSKgMturo\nqgCWdEw8elelROXhzi+qIWTKm9tngZcGE8uJq0j9XEE1OjKfVfrKFzlKF7in\n/hbmb+gCb7AO7BaTHmB70/P8EQsCo8aYtJ6fN3m2YdDIgpfY3IGTAcOsLVeE\n9J7Wz63oDkwV94I0EZcnKTvDQ091on5YHuzjABO/JRc563Lf5NF+eKo+Zday\nv+n0LTMw1JemIR0vVBboHHqZN5Epz+X+3CdX5xCc9pGvnIGCUOCFhmA127cw\nSnCbInrKCHqk4/e/RgmCpcx6xZxUMKQhWDzFcXm5GnYVQ31kVyIJx4UrpjWy\nUjIfuOlcyFCoKKWg58ruF41RaO9F7TjN0gxDrcUloDzLmqO3hHZlA0HNJPvW\naHLikTCZvLeEOqIhL0db4R206ZDdx6HCOd2c4QWGsaUGWwyYFeCOcUCniHqB\nhfVLU3C4XxHSLNINOBM4A+QkbPlQm5DgLzOTqZS3Hhn0GZQh9Tj0xpCgJec5\nma4L\r\n=i0E3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDwrNzsLv0v3EtN7kaudaem/IIP84lY5Mxf/3qAjXbfYgIhAMrq+wO0U9jR4KL/LXyNJbhFQ2RPivmduL9zG/t3j1cP"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.6.0-beta.1_1595012478738_0.4039117077714136"},"_hasShrinkwrap":false},"2.6.0-beta.2":{"name":"nextein","version":"2.6.0-beta.2","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"3.4.0","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"f9f6c6a1b922a88e6e6edc65e1554e02908ea96a","_id":"nextein@2.6.0-beta.2","_nodeVersion":"12.16.1","_npmVersion":"6.14.1","dist":{"integrity":"sha512-pQoJGsBW2doWTv1IIpAx/6nPoZVoUbzcTK4q+WBOOYiI5/Ti1LhdMN/dh2lMGUXjUfi/1BBVzym8Bh6dXUDlhg==","shasum":"f2e8355443a052253b5bde9184413f1c0ade68ff","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.6.0-beta.2.tgz","fileCount":30,"unpackedSize":122108,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfEfXvCRA9TVsSAnZWagAAv4QP/Rs6SIWWBVVCmYyEyfOC\n+dNnlUHNeccZBMeXWpXUpt+dRlch++Ch3brLcxHCJhSr/s33lScrBg6So+G6\nKFfDLPGPIgxA+ts1YVqSP/VUrlit6jC8KN/j9bK3uVM9ZQedtvXWCGMmHqh7\nPD5ZhUUOGlWpi7x+MOoGBgXgmpfnLpv72+kVbje9k+7roQ7y7OVP96xtd1Kq\nfgk3GNRbQzJZUHvF3Xuc/0GA6OW3Y+0DsYvIXDRcpStEEk/CjM+FlKp+xQ8q\n6PfY0lGOGlyDsepl/MnXSXpK7cPbIQpIxd4HntxNbnwZEqx14gFGZBB+6wAR\n9vGDUFoPBimnnlljemKL3S2DK06/PGa1GjQmCkE+/VeSq/LpcHpAMTd+Bmy0\nXrVEXQsJIE7Wd+AI4OBOXVEPY7pN620rW7ojftLUEJWZYarzNWE9sT9QOfwx\n1ipd6dLn796Ov1vzFiMGoXIH5Wt09i1Xub4G74mMF5MvKSi4CowydCYZ3I0b\n7n2mtHpyKNZQik+whanepGIsrPXO+sV3Fo89EhhYYNZHih91ELUP5f9Xy4SE\neZ08SnPkzlydWLiPbb9uxD0aS3ZzSPqXS6mdP3cTOWyOLCoEo2/IzjhtXIGb\n5kE4t/O/+KE6QJaVy452Zv4JcBiCBbjK7vemBO4Yu0YOQp+KX8A9sJEdTI8I\n+pLr\r\n=GeNS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIH4mFn/UFTbcuMEQWzlEM7KjPjr3/tseh0SP01Ofd/RyAiEA70qZe5SQA2NO3+DDrBktyzMf/pyceOULhg3eX/jkvk4="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.6.0-beta.2_1595012590862_0.40511915261439535"},"_hasShrinkwrap":false},"2.6.0-beta.3":{"name":"nextein","version":"2.6.0-beta.3","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"3.4.0","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"76c50d3d0e2d9ca6f10859b03bdc1491f704eafd","_id":"nextein@2.6.0-beta.3","_nodeVersion":"12.16.1","_npmVersion":"6.14.1","dist":{"integrity":"sha512-igO/hNP2XOnP7b//F/nEaOnaml9OwAHYNH93dkFfie+wkem9UDRv8qw6W2m9yeNddVZ1PV8jKC64q0jMkn83Sw==","shasum":"2cffaf0fdc1b4cf495109df9a9b9120934f4bdbc","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.6.0-beta.3.tgz","fileCount":30,"unpackedSize":122114,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfEff1CRA9TVsSAnZWagAAd7UP/0MUPHaFbHtcrQ5yswNc\n9evfyVqkm4qyRsmZ1r+Ak3Rm0tGc98AVrylCEx1YbjEcKAw+EYyMTSfKjgnP\nz8Ck4Tzy0jmd9vBNB9yjoAkfAOAbKJFadDemkoK0DVWEzO/W092dGfE5Upp7\njIAk0BZcnlYz3kJEL28JJybKkRTC1sR+dZa3aGzgX5A2V0SwoDZ9e/xRRRLo\nUUJnJsEPJof3FUs5r+dxTUrDtM17fOh9xtZvVnm0u6MTQh/8TZYbzS3e27eY\nGK9lu/f32ftYVjX0BxiqO0pbMNQHLLuSgRYZdWtrhf8meaOgCUzXWzWPdwp5\n/2YMq5Xit957qJlV8b//jCqdVO95tX0OORgoMe1RqgDc3VWeon7OcjBhZ6Gw\nUClyvTIg4aaOGDKU5kTm7LVlTIkTlM30TvR9JPk/3nW7v6iCuVbRBaaehfQ4\nBjod2jNffa/zGgZZ5kf41v4L4vsxiUZ5+9WYgCammeHQTd3/ox0p9iajZPAw\nKrO+x1vFgwZNsBPdpoNfMQP94140Tv9DVVL28ZbXNjeKOpn47sFnL8O3qMdJ\nIfDdfQXg5O1tdDJ6JJONiav/C0dNO5Adv1A/SceZFL/mKS0PPkKiWSD8fw05\nVIBi4SlG4Fl8dfmFMDD/eeY71RrfJcUmawMuWLPWFeI80Qahr9wR0+avHSUr\njh5L\r\n=zWxL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA+Oms6yjTjjHVn96SdvJehJQTNfuZy8ZGYTycK7S5xwAiEA2nAN4P6Dkv1+S48slc+grtXKa/avEn9m8ZYbsCavcoQ="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.6.0-beta.3_1595013108617_0.6523131518750283"},"_hasShrinkwrap":false},"2.6.0-beta.4":{"name":"nextein","version":"2.6.0-beta.4","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"3.4.0","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"248f8025148372509677d3021f5c7a5f5df773df","_id":"nextein@2.6.0-beta.4","_nodeVersion":"12.16.1","_npmVersion":"6.14.1","dist":{"integrity":"sha512-qoctg+bXbEdSFZW9/VZiiuWSP6FC+NeuBUx4+AdKx8BVd7lLbdFSgvQRG9y3f5hWaMPLZcpEp3ormeABB7dPZQ==","shasum":"8faccbd0274bb8d1b60d7a196578fc9ac4dc0284","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.6.0-beta.4.tgz","fileCount":30,"unpackedSize":122140,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfEfibCRA9TVsSAnZWagAAYx0P/jv78KCcjf6fmQzJLjtd\n9YjOYIZsdooRr5kHAVecCXi6oy0ibTZ32nAUwrVjJ0KvlJfhUiVjUL+Xbieh\ncRtHCTVLa/j5C3S8AojBkKchDHNWOAakNkE8oCL0b+k0rXLYsPDHNz3U1w70\nFO0aQlLXL1iIQINjpYkQl/igmF/ZqMSY7wWpiw+OeFpNHQ6m9Ps8Zkmb5QID\nHrm+dLtngJliOK/vcFWCAK0vym0Puyw/0JEFK28IRuiOoPR2DuVMFfs5EqUE\nl6B5CAWLNQQI7JurAdZuY4q5OxvzJFnsFM9ItHwBpDFz7nrGNZuFsNHXnRyV\n4RII+YvXpD0j6O3+juicXYJLousO8WTnfUHKpqcTeqLcWmkptgaQkvzDtH5A\n820KF6UlQGG4dvA+R/GkTGbYzSH7dcaD6T0UzbMEBh03lRlZ4sD1+bUWOr9c\n0FD86njMTuh+MsPXkrlztQTd8lUpiPn3gFqRYq9KbJQghAlSnt+1PVAClhvU\nYzuEidK5iFUMb6HnoSmLzfyhC2sUOAt0HeBNfkWLptfpteTlgsiq9SsFxlN+\nN/NXFBbmMN/ivpBTJ5ZBq0gas8500c3eVMoDL93JoxfFt2aZvyOr0NncHwdc\nyhKkykN+Ibzw5YZcs7saZLfBqZ82kEv0fRYSgnJ9qzpUwQWKL0nOprhsqcBN\n+W7R\r\n=QyhP\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIB6Gjm58U82UjrkFybGpNdxVDBXWtc0d1RQ8+hjU+iotAiAHU+BSsAK6DghDdHfPvNVfxKi08KJGqwWEtlnr+h4Igw=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.6.0-beta.4_1595013275509_0.7452864654038267"},"_hasShrinkwrap":false},"2.6.0":{"name":"nextein","version":"2.6.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"3.4.0","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"gitHead":"5bcd83c67d6122f68255f5c9d5bb00c7d2214073","_id":"nextein@2.6.0","_nodeVersion":"12.16.1","_npmVersion":"6.14.1","dist":{"integrity":"sha512-PDnwXvDMCWgX74WXNpdFAOA9wWEYHMdFwzv9a4UoyK5zRjWEdDOEXwL6Riol/Wh2R2Zh29vFwWJZwpHNrzeRMg==","shasum":"0bb588b926095778f177a38b830500e8293884b5","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.6.0.tgz","fileCount":30,"unpackedSize":122354,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfEgDRCRA9TVsSAnZWagAAbjgQAIBdaGQHX/m+v5gW1M8I\nV1WTelBinAfKCP7dBlyu2c/JbddAogJVhHXZVhYNCjcLhkbT6MfGG4B0amn/\neUAHHvYbtxfnHt6iC4UL9v9gJnjXQVUvmk7ufGaFWf7Dc2rJVxfxttYmUfZp\nuSj2dLea1a7NFUGFVZfKjSU2sQd7FCH5FU1xBMzsM9FgbRbXyryMoQF0zGSo\nybpQ6GSkKhprwlaGcVzM0sXyWvsBgMlhJJCe9WWdcFnE6ypW0KNIAaXt70Cq\nAhWgwu60tvsRCrISKXyPTZK0GMjmcABYxuIRKgSqdMKuo+50sfnlxg8JQ5z+\ngcc64uqnBZfED9FV6N9lAfJWWVZ69AYKOMleiGwajc0jMcQmZl2wUPtkh2hE\n1RpvwN/AwqdJ8uSBclhjxixZMs26qdG6z5HaqNpzS1tBlryRCYVgg2orqDtT\nmtTYwHem04pH3/fLZ312MPh6A3i8SBQVswoO+p6o+JWCcAjkcOaGIjqaUHeO\nB3j728AfTpzy9esOrSCHh5040qiVhgU9VHtDssdXtY5POuUOnrbyeDCkW+0a\nyWFjmY1VG0eMuuaihj4lOAwoq3QX5ml/+ILhYGpACT9Z4GC8Pe/GbiOHaO6I\nEITVLF6E4g04yidFflVVfLC3H/5h/KegRfUEiPhRzJIqz9Tb3Y5Kii+4Jg+Z\nr9by\r\n=Rb3Q\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCvp1XqMWNEm9I8bB0OQLXBmTy6KDMKh2ksQfxyAOexSwIgdScUZfdcjdQBZcfqR+Ee3Hog2i744ecG4ANlvDiRHwQ="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.6.0_1595015377110_0.45530803463104164"},"_hasShrinkwrap":false},"2.7.0-beta.0":{"name":"nextein","version":"2.7.0-beta.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"3.4.0","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"5ec5c4ad0f31712d7950eeb0634edc275308eedf","_id":"nextein@2.7.0-beta.0","_nodeVersion":"12.16.1","_npmVersion":"6.14.1","dist":{"integrity":"sha512-QeKAoadtlrDXRL0WT/0aZaRVb1yumPQ6ygAj7x5sixJjETjuRDuSUvuxlSw0ToS/x0LqHUvtMlWrbb9MNtvTDA==","shasum":"e681d20c5a287968f8985289a6e395b72dbe47c0","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.7.0-beta.0.tgz","fileCount":30,"unpackedSize":120608,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfGcc4CRA9TVsSAnZWagAAl7wP/iH9/DawIHyjV8aa1aAY\n35RPpW5NrjmxEy4lVf3+/+xrIrjG//BxET1XgnQCkSYRFYqLH9HKWJHpsROE\nCUwjtCl4fxasJFMXSm1NS6GCuHTHHjWlKzpW0glC5frmohpbtqBOVtEFuteM\nuO5Gb/nFGkcw7IH8153U1pHuobd8SEFJDoomkbna1+jSRT+yzG/PIkHqBZA1\n8v0GyG+WyDdIc43BWppPwtnkWfTttTixPuvJrbwHJDGHj+zyl9vUkybJo1uO\niqxwL0rgTaYHvN4zDnn0HNgONppMk+8fm1Mqp5n3/K6w6aSC0rtt2ozkT9gT\nV0GThC7D7KUonGxJ2DAEoEyteM+pek9Hcm93Wn99/yv/p/xYUnwMPHrC+OF1\nHudNpUJs8/PMKbLoZXohj0YkUP56tXS6tAwZ1wFGuZEXXwofjQE26oNj94im\nwr1VUqahz3+P3OSuDueAjRk/ToZL1hyTwNxVUoVsYF41Fo7yVZ1APaaQmpA0\ncrBKGXmUJxA050CVqm/WfU06Pn0jEfNJCbkyGSe+T25iVKYBhd/AE4w/k8IT\nYzypm3tk6WcP0nyglBxhuGS9lI7nX+s5fMIVU9OXH6Xl/LYkBViF2wNOfZqa\nLwEyTodP+J9tHY/IJFJsrsOqytqb+a/Im0Y9btWSuyT/oaDncDO/7aHH8zDB\nKZeD\r\n=htqQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF7U8FIMLsd0g6cNAqhyJPus6HbCTHnnBlVjWyDC2oGuAiBvFI6fq5I2aAjwBW3/bg9Psy7yjDsUGv2AwbO8Bf9Lbg=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.7.0-beta.0_1595524920461_0.8914311007494866"},"_hasShrinkwrap":false},"2.7.0":{"name":"nextein","version":"2.7.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"3.4.0","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"gitHead":"cf5d71aa5e0a81a66e9e265e5b39e1d0fb6c0bfe","_id":"nextein@2.7.0","_nodeVersion":"12.16.1","_npmVersion":"6.14.1","dist":{"integrity":"sha512-Bi2nEM3sbdctwU/oDTLYD6EijU/r8M6uOT6Z47bCZp44Baultv3McXZocIQ2JFZXa3FlY38fHrKpfE/ptWYHpA==","shasum":"bed33b78031ade228b51d83e85c613d61a9a33a1","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.7.0.tgz","fileCount":30,"unpackedSize":120748,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfHx1RCRA9TVsSAnZWagAAKzUP/j9hSWWBgoe3U/xddGcK\nTa4U+QLKCtP7nAOKG7+N9qyvA7FJ2L+oqYT6sd6kZj1iu0Hv3/ElhtRmvalN\nIFlp0AepQtdvTLySVcZ6eAJxUxbpIUwdtRlCECsDl4WYypiyOBbpWxjtcc0o\nEaZg4pr7k0yqWt7yp0GxLHxkAZuCj5tadVQTxZseD2r4ZDYxWbPtKHrQa8YW\nWSLOEQzRvFRvjknfEwqxX7m2q1wEP7eiRw3cDD56ca4h2nTWgwijsnF30gEy\nqgMhj208CwJ9Es6K4KIyHuSPB78lgfm5MNkwjNKZyXrg9yzMxlRe1If70BYM\n9IAq91EoAtjwamWI6WUvladcKQewa/G5/5TEknIM4wGPP8f9Cqj/+Ulj63Tv\nIkMl3BWUeRrgwGJ6enfZFNa8AaNPYvROFTD2JMoVQ9BXTQjWKOkPAhB0SqNs\ncsMRqa9WZGSwmxojZ8eAoAxMIpDphZhM+zBR3I0P0Z+kWMirDoa1EJFg5I9W\nXB864ueboPJIOqL08GYxWoD0UzLGFtKLanEANWD9edfdqEbgujfvwMqTTPWe\nCwjjmb3qAY9iPTFt3FELOD7fBtbB/p9dWa/MBh+o9PggoonKcGmlGhJh+/8V\nt3kkbIIGgFe71XKxUehRvtNviPnCleuo3K+OaSfN7zKboQ/QZv4I3BaK6nZt\ntCBW\r\n=O5uF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEBLAyICPCdeH94LW7xWpZpC7xJbHqzFYq4huXP3gS+AAiAY4oo/WvA4SG13U+UNZz5KZxoEvBxjtMUYcaMExq9PRA=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.7.0_1595874640792_0.5138433564637064"},"_hasShrinkwrap":false},"2.7.1":{"name":"nextein","version":"2.7.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.now.sh","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"3.4.0","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"gitHead":"9602e077d24923b10c0e7c5c86ba787cfe1a6fa3","_id":"nextein@2.7.1","_nodeVersion":"12.16.1","_npmVersion":"6.14.1","dist":{"integrity":"sha512-a2aHiyccs5Fe2TSoN9IT04LL/8dBAMTuyw5YgdzhUoDcdNK8brNLhpW3z5QWHSBJ2bmvMdbI5OuVfzsIGf9B7g==","shasum":"239181f98a7ca7efd83eb17d66ee0cc7e2063c13","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.7.1.tgz","fileCount":30,"unpackedSize":121353,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfIJq+CRA9TVsSAnZWagAATp4QAJn1wgAt7VKPlAN60hH+\n7qArjde3ysfwP253f81i2pM04isgg9YnkCVi5CSimLzOHVPa8izDh4Ld9M7l\nyXXxhw3CSDF2ldNnQSJydsIVzB9xmAJWA0HY2Y1l8HphomDJpr4N2SV9lOsE\nii31bAubEZpckycRMcY6CfUXBUat9/HyLTJZcFQu9PvNoz33vdpalAU+4myD\nOG+bUbqUolHdOPsSAfGIv7vwmxpeYSQGyPzjvRCbD5OOWgcRx7GNuBPWm8Us\njalxdyfRTOwcntcmnV1YqfJPL+C43nC+YcV40xpycapDriEPra085CKf/uJ1\n7eOJOxtNu7NXdWSucL3kSeYmfDOnxxTE5CTeaL2vf512TPbnyYAtmPgdlvE5\nHnizMMreuegIIYbg5HVcwl/x8YoOoCT52hpwykfn6o1A4W1xXAj2S6jiZK+F\n7WJFyw56xIG612DOrGF69DZb4bLdIVtl1C+A6+nYhKowShC/cYle7n30/kEc\n/fs/GCnUkHixXndDJhiMBd9hi7wpDmX/yYon+nRsRplCBjh1d/p0lEU9OaAh\nHpzzgrev7kwED/vgVAWIognr9lTfA3kNrP6/AgG7TmB6XicaHIiiGUMU94DP\nelS9l7BQKTJDTiiHfc1eQS18JKxhOhf8NlfGRCR9BmKlhAaEoxgdJFIkNSI/\nUL/y\r\n=7d7/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFITh5S8uoH3FbW3Rz6wu61K9mTYBc9mjv0YVXRPtzSYAiEAwCr5tI5HQbvcMyb3L8iPdQRloGiGXbRk0sVAg/6Zw/0="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.7.1_1595972286262_0.4035276383415001"},"_hasShrinkwrap":false},"2.7.3":{"name":"nextein","version":"2.7.3","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"3.4.0","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","glob":"^7.1.2","hoist-non-react-statics":"3.3.2","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"gitHead":"acdcd0d3a05641e80a5a02f479f22f8c662b85b6","_id":"nextein@2.7.3","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-Znl4TXlkflz7pKX1Yla25wHEwzklsQgh8caLKy6REjdghHot4TCPlgDUft5sX0VGJkoBTvd14mrsa+PUdzrsng==","shasum":"3ed9e2346b6384ee131bd07a480927e7469f4c06","tarball":"https://registry.npmjs.org/nextein/-/nextein-2.7.3.tgz","fileCount":30,"unpackedSize":121886,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfOCr/CRA9TVsSAnZWagAAMocQAJSn8HZBlZWvUWkuiVjD\n+YzkvdIzkbIR3kK5Vpn1c2z0i02c91DQV4Im9oVp4HcvUDiwxCaW/oLgj8nS\nw0PoZxHszlcOWuLLUvXx/Bpf9/5J7LXhVTPsc/0+bH7sF0YqV4kcFbs0bY2W\nbSru82SiRMwni5am5BrlApuZyc57RdMRCa+3lpJKjDJ8BhK9YK6jxTuV7u2d\nOxdMT8Ead/hvgMCGyIkzqskEEq4KJwQCFUb+gP+T+Ar4+n5OY+HsDdnwIPgb\n14U41IqftwdgDMf2aOYUCdATiNYLcMglA/EvZVkc4eKj58E1SQOxcdKib+xu\nkkRUB64w28YO42uVuBPlX6bi+bWK//0oxZ7t1mE3T2RviBvspeP/9LjNDh2y\noQhanuEwBwhlacsEmqEAO7QvM3i/8llAK0/aQYTBtVjbvaCYS0d+7GSlZ44z\nM3VK3kFHFJetzpMBfD9G/siH0nTKIuK3K/fIrM3Vg6R9YveHm2jl2ScsUVIy\ndRZaiLMuAKjyMSnpbGjAPVnz5a+8G7U0C5LKGVxKpYmuj6lWO1KM7BQXLzbc\n0QNbG3fu84g7Wrat4YHFrEhJD631GG0jjXZ6iv9cnvSq7BLdsmkSNYh+6tbJ\nHf7GWu6+Sqkoy0Kbprly8V3guqyyj7SlXTwLBwHOSooWJRASOcqvUfbXkhCe\nqBvj\r\n=GYVB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGBs6xUxucAekWZmve3fMu+FL6JoDAtsVEitRrAmnDq3AiEA4nPvbpYQdh46ayoCLccYboX9BMTwyXN2SuUy5qbJsJA="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_2.7.3_1597516542895_0.7938003590927967"},"_hasShrinkwrap":false},"3.0.0-beta.0":{"name":"nextein","version":"3.0.0-beta.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Invitame un café en cafecito.app](https://cdn.cafecito.app/imgs/buttons/button_5.svg)](https://cafecito.app/elmasse)  \n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"d63521c851870669cb2b27590b02f75f33a27dcd","_id":"nextein@3.0.0-beta.0","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-sOK9+b9vYomgYjxU0yjcb0xm5PjjITR4+RLDwJJcbMbi58NXJVQQ7st7peydMCXsRcE1E5ehmHgjkShsCRibsQ==","shasum":"0cbffffb56cd4ccf267d6ba6fadbd9392bf2e12d","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.0.tgz","fileCount":39,"unpackedSize":152799,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfUPZUCRA9TVsSAnZWagAApIEQAKT+sj+STHVAHzrbl0vg\nwj+zfX/DQcdUixVQoz7nUseZo3Bzwu3Sci1heuxbyRhb62TC7tR03aEODLrO\n+VUq3ODmlMAPkENvzCHRzOXZeP7bkccw2Ix2BuzTsB3p47JvFPYyCqL+9cbD\nKLpfzlqM5kAeNrzFlxXiOqADU0KPPM9xbcMFDM+sZZFtAXpQkJgnhKr7AVR/\nbK2FOjZmec2mllF4QfgF4ZIy570/rmk4IoE/tApW6HYu7JRK/hrYNTEEOnYO\n0/6Y//otSkfI8rIQjqnQ4ZasfYJSw3b+HYXIPysOyt3/sGv18CzseKgN3p5G\n7Z7HT/KUtZiHIBqd8HAj87iUwBNcEKOTZcYm6Ispcv6y0Qwjr11XTsSjDI64\ncSbpyB19NW5DP3jEFTah4rFAXFAppbp8AVOw7qYaPpsK8II5ts1GrC3PbMK7\neXOGSHEUGzDGbPPsPR8ZNYCoVpOQUChtYtfOjvhvAfA7PQcwaJKq+emrUJ5k\nMYFiTRclPzR/qYKLbrHv2YfOxTNrOpySu+4cm/XQbtBp79GVDECXGW8YS0gS\nwgWtd6DOOufggbqWST7x4LSaZTaOC7T3XH3Erh7Zev8FsXMiNkq6H50SUCmg\neAVTbkKoWcR5+i9DCAOPm9z9/nfvoRPU1dn3Cb6POCysn7Df/uqONS2c/3vV\noYsU\r\n=21J5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCOOjkAtUyMicRQsPbdzX6sh03E1ftwCtN8WFFo4ocWVQIgRXzOjWroDSQf2vEWDWxouLZxOS7Ckhy8Zx+lM8div5Y="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.0_1599141459597_0.21298048927719804"},"_hasShrinkwrap":false},"3.0.0-beta.1":{"name":"nextein","version":"3.0.0-beta.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Invitame un café en cafecito.app](https://cdn.cafecito.app/imgs/buttons/button_5.svg)](https://cafecito.app/elmasse)  \n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"67f5289a8d680f2107f83a55e56ce4dbd5869b42","_id":"nextein@3.0.0-beta.1","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-Vdh0GpI7rtL+PJNXufiP8DrGi/oRNPOFt5m+pHnF5CnzBzhCqmuXCJJZc3TPdaBE1FhsVH3qT61eyFQ6R7Qq3Q==","shasum":"ac3b814c22422be77c1f8ce7cee55c8ad8cf73cf","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.1.tgz","fileCount":41,"unpackedSize":146023,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfUqtkCRA9TVsSAnZWagAAc6MP/jNzQniIU/D9cacmSL8S\nSbf4ZKUypy3qsGl/jCVDXoeIE8rQ3cuutFCsQm3KC4bCf0xSF6cLoQ5tnJg4\n660vr4GHDfGeiTc3xtiGXfLaLo2vPqP9sE3rXxtmTEEnpTkRLkQ9dBDsuRDp\nVwsHbde017FDZrVrD73FtHZAdyRgYZNWVTeOwFHrWy6XB4EBFLpwqGzXNZcK\nEHuwtZLrAtB0tygoZgEdfcFqYvdt0TVNOeGCS8GYadLbivRnUPqhJXBIfySh\nsyC3XAVfNwxgoDgYcQjAJU+Y7+W/Hp4s1mm6oxZfSZMoeDreeLCTip3Dz3qG\nnz3NVgMtmUj4Kkl5jWrm1c7v2pJPL4gcqxl+jnNP3PV8AqkbMh9mRFg3n0BM\nKl/GEnjz1fz7UmW4xoa6IeKcLHztWdCjGiFgQPAN1xDcEXPboXEfL3gKpHDu\nfH5+JNdWSvOGMa7qckYIywquG4p7s8n2HXjeCn5INEMs5C8mlCa1arI3scve\nzHYplpgWVhIvkgO/5tDVl3aSytGlYNchta2Q+fkb/9JAdCy0qPHcHeFOOcG0\nsU2fO74LkgDG8U4KEd79iRW/gc7NRg3v234h1hXDS7w/CTBbBz6nyhU1gVUt\nKEe7Rzz7zz0+vxB/POwP3+6L3J8+J44XBNOmjieMJi3csKefZcfqurwtZfPK\nun+p\r\n=ejbz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAXtEnogNg5qALa2e7h8gfpW70+HatHiacyxcc6pCW8GAiAi6n2VoTLAJZA1qsvBKbCE9wry3Z2CL/yPww8fwSq9pg=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.1_1599253347655_0.5655276390822985"},"_hasShrinkwrap":false},"3.0.0-beta.2":{"name":"nextein","version":"3.0.0-beta.2","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Invitame un café en cafecito.app](https://cdn.cafecito.app/imgs/buttons/button_5.svg)](https://cafecito.app/elmasse)  \n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"d93c16ad5f188d6ca1cd797aec439a9584f41485","_id":"nextein@3.0.0-beta.2","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-MQirqu3Sc90Sges1PUBz5f+ZGTRz2KY7Mes8zr+9nNKy37Zm0RhjP9kLzgdDnVmfNI0vJHo+kM2I+anFYKLfhA==","shasum":"80f454146c19bd7525389c3aef4d77606c422204","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.2.tgz","fileCount":43,"unpackedSize":156856,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfWOvTCRA9TVsSAnZWagAA5iYP/3S9u7lenRzFjUWqNlb4\n+uF0xi8QPNuQ8s7tpEOyjzviUc89oicPQ2tcWvlTrVptJgOGw97rla2vjsvv\nbxNtlUOFXF+DbZsWBe9zqFkQiImTxewziFpsa0J8BsgiMdGXb34zVUqr6+7N\nqXGfWA/Nn/skqjbrMzfOjhxRfbKZSE98lJHGZdPJz/A6viphN5ZXyshAJuun\nbkdUOW/EWSHVRFef2UpiCwguTFZjPTf4pTIpVXW8weMCASsnjD+u5cTnLqIg\ncT9AnGmxt7YKHdH0u8YWn2RLx7klbff6VQvNyqc5m9zOttX7n8BhyfjUI4KS\nu90sJn1pAwpCrrjbHISsyxPdiepgVcIYA7arSoBKSdbjLxX/CNlVZwlYEEYw\nKd3nvpNb8xKSukC+HwvTE7obhsjqUkWihlDJKdCTIEG8PJfHA+qzz2pIo1L6\nyUfyXAni7tmVMFSGnsdVswlLKrcKVWKV/wHZA60gAIzHMsISQnpIwLRNgCyK\nxxxZExzk/CR0Rw5jeKX/5Qm7MJ6nrNouLc4YBO+YbiZ5UqEscUZ1iiSinwlK\nwBCWQUQXHPwdMQMx7DhS0rg1DPFfa87eW+iymsErixiwqSzkL0KCEb+RUfgH\n/+MlKyqVAWypJBXn9XZGFyMoOuBVXuYv3hDlopBPocT7DBn34rzF8hOXlDgw\nquCj\r\n=+2ix\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDjFwlZgWuxmiZBmSSV2jvInrh8CMNB+woR8Viek3/KDgIgVUkCj6exx1TqH33nLv2RzMCzWaWGwfBgUm2B+iXD1a4="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.2_1599663058674_0.0157182193284644"},"_hasShrinkwrap":false},"3.0.0-beta.3":{"name":"nextein","version":"3.0.0-beta.3","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^8.0.0 || ^9.0.0","react":"^16.0.0","react-dom":"^16.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Invitame un café en cafecito.app](https://cdn.cafecito.app/imgs/buttons/button_5.svg)](https://cafecito.app/elmasse)  \n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"a92ac1bd37584ee3f21b08bce000490183bc527e","_id":"nextein@3.0.0-beta.3","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-fIVP9/9k1glYSSL7lYAORoKAreU1dyBkxoy+BUQ4IKX2fQjAR7w56AOvOepYqxn4faOpyjP5mILVTwlNpHMFAQ==","shasum":"9efec3c8ce3d250dd1138515cf91c56b50bdaa3a","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.3.tgz","fileCount":44,"unpackedSize":158253,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfWh04CRA9TVsSAnZWagAASPEQAIobXYn9AEP40gYEEUzo\nVrElq7TDUVfSWx8k8yS5YXbZ0HZsd6XRW0/CgsfFmZ0ZEUr14nZRNz5DYe/M\n09yx9bj51wfFXVX59dzsdNSmS/3g3xEbNVLcdb8Y31sm4N8boCji4erJObyp\nMY1r33jZJpLq85Q25suBSiwT5Z3ZySdgEGodt8Hy9pNGrZ2swkW8HA6C0yXO\n/rZOJwQPqUxa65zK3sx9LmH7aoAlQWcOseaCTL+pQ+dTOzZ5C/iVEe00mpr6\n2DThdhoZBqJT9YtdNr3cDP2vn0UlWB26hfM0923CD71xlDxtycKrsspItfQC\nWXikrw2u5WU4pUn20tBFQKRaD68aoaapvU6mIAo8CmXVh36Qw8V1p3b0wemb\nYNSqwVpNMX/TMJmc+r/OqHaMUnG112jP9RwG3mLomCC6j7SDEQSiLOnDAxv3\n7TPWgwCD3hT4IVFYmEwfl142j2qmNPcnNEiUWLq/L0CBdq/jBbsHuPrMlENN\nvWaIZ2Uos+5gFx1TR2vkrtHv1hIv1lLeJztKyGX91JVMpJWaP7I5Mt+pPxq0\n0nm8gEDzaUvgjkBCnHYs7T4DziOvXPDkJ9KADL/FfKPhb+7q6Y0fN5qPqWq6\ncFMteQ/Yy0VM64+CEcXD44AbWKse+Se2jzMubkdOeLAf+jZSvMqjmD5gQGQI\nyRXG\r\n=2DFs\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDwBY8Rt4Jo4LRic6mQ1Pbatz0GJuB3KDWLX3/vjI6UrAIgT7nLhjl/8DItf5FI9dluNV/ljhmPXjE3i+JUnEtmWW8="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.3_1599741239940_0.550647165960827"},"_hasShrinkwrap":false},"3.0.0-beta.4":{"name":"nextein","version":"3.0.0-beta.4","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0","react":"^16.8.0","react-dom":"^16.8.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Invitame un café en cafecito.app](https://cdn.cafecito.app/imgs/buttons/button_5.svg)](https://cafecito.app/elmasse)  \n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"514199a1f2b448a61d73fbfe8bb2c4664c65dc39","_id":"nextein@3.0.0-beta.4","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-8DUtCUyNlJ6d/CfSiarnnGOY18ajN9VQy6AkwwKa4NTf+rC2IrLqwcK9CPwcw8pt3pt5d3+KY8G04xH4G554jg==","shasum":"3014a0e994d4869c0b522f833dc2d0777d38016f","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.4.tgz","fileCount":45,"unpackedSize":159927,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfWm6BCRA9TVsSAnZWagAAdccP/i8tvpOCtFVqJp9K0oUV\nmlhLGhjiLrwDG7OKhwTsUqJmeQLFRA4SC22f72w0vc36iYbTP5GxBTd7E0dj\nrfPIlTbVIh8+vqXkAm/BQ+WrV/GcJdr6M7+2R244Jn/fnj0A3QWaKH6iO957\nxMqlZoSBRPQPTsgTF2ix9M/XwMmy2gEb38K4Dgk/LEGcaPzYUgaF+3vAzRqS\nhWarixtbuRc8wpo7qHHQ5JmQ9YJBiZwvOeFkRmyNgZDgi46mh90dVcwuC9qv\nRUMzdV7znoXiF9ybOApSST04TdIpCnPqiL1pbY9D2nLcv8LDPQnxfFXHp7c/\nhxycUN3kIRFPgXrcc4nlq2mtrZ6FpZ8iYecElf9FfzUXKyo3gXwAkoe1hiZE\n87Tkfibq2CCIaLFLMx2nMASI4H5BHqr3TbpLbXvSvKSG8rICyd0zEwGGFmwu\nri5khsO/LwLw8YtuEu92NwuSmSuBIK5LfuMxSgxc62Pu5vr1GQNX3wQ6lY+1\ncHLZzZWxgJk97wLReg7/KTjTBT41qTCOmbOV522by7mil9s6/Z0YkFqZNmoc\nxGNLMV+dm5uDWw7OZI6BtDowJP+E000X2tSoWFtgLOrEiJiROrU/ilX333Hl\neTuec3LLEr/yt9HmAP5PGiYtFJLk8Oii6EriMczV6WJORfFp0ZHxjg7nMzWa\n7THA\r\n=bxx2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCtC0e9Xn1DKVvXIByrEgxW18XSQxoNZubXKxqN5hs9ZgIgeeNKErq3l6IAZTccCeePsxynOuRT7x7z7iGFMTXIp7k="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.4_1599762048733_0.0666616245271534"},"_hasShrinkwrap":false},"3.0.0-beta.5":{"name":"nextein","version":"3.0.0-beta.5","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0","react":"^16.8.0","react-dom":"^16.8.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Invitame un café en cafecito.app](https://cdn.cafecito.app/imgs/buttons/button_5.svg)](https://cafecito.app/elmasse)  \n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"443e6a0ad8fc8508e10304be8f8d33978a1394fd","_id":"nextein@3.0.0-beta.5","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-MjiwffkCUnrwi62/Udjq5lZJU9t8kECu59nDrW5e0YyW1DqZSa+qb1R/B5tk3OUvPVl9rvTKT3I7iS6bOEc+3A==","shasum":"b044ce65ca70f08c16fdf1db6d456757a9a17908","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.5.tgz","fileCount":44,"unpackedSize":156158,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfW2X7CRA9TVsSAnZWagAAtIIQAItUa7Q0z0WSKoF2badu\n8V7MJevr74mEyAeD2vvFYrlb4Q3lNe2J71KECaLDJ/RxKZgzrkJqDGrHocm1\nX05sVcG3y5q6drDIJLlwJ9/I1qYQ/EN/jhr7T3r1Ztm7LF9XhV27N9nDsiF0\nCA2R6PvqhDeyqJ/pNrsuO5XGemrq++uil8X5njRblIE9xn9osVwULfi8SX+r\nUM4uO1VYQp0x/t7Qw9HlP3EhsCg32CX6fimTtZM84BOs4GCTNeqROb2jg4hQ\n5QMQg7oPxGW634z+HZXfNjNIXaAsMWUWmPrKOfVYTObVO6vzdPuIKl9mrc9e\nt/uuod/v7XYbVJWITMkmlCck2v6SBiDJmllmCaJ4paN6V+TDwmBN1FceSWQt\ndBfRn5M4zTVpRt9qudk+fUCWaUtEhgnIp8E4U14NplxZvYYzw1n1jp/oEK+X\nIR8b7b2Yd3zB138gKaUn36Sp8Uh6ImVAbtOrz4aZel0QIAFaQfg8wjtF09Kv\n9WQ0UrfVXZywYsz8K5PS0QZKferWGjGFMrWt2zekBRj9rPq7rl3TOw/AHZ3A\nPAlIz1sWmHnmeC8OavBgSXZDvXQr+22TA5H9ngftHokMSlM0VBQwgfnF18x6\nIcqstOLJ9x6mZyUPfNDk/yy3tXrIkpMtEzBZ1FEGDBWKBJnzyU8McQmmtMMe\nWj1V\r\n=cLav\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIB3/sl69g4ZCmVVYWSo4Rg7xroq0jRj1zVBs/LHp3ZVWAiAkbM1kFIIT2XTCSmlr6qnVbBaizdL59H2xx9XxMJTYXw=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.5_1599825403308_0.23137545259360648"},"_hasShrinkwrap":false},"3.0.0-beta.6":{"name":"nextein","version":"3.0.0-beta.6","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0","react":"^16.8.0","react-dom":"^16.8.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Invitame un café en cafecito.app](https://cdn.cafecito.app/imgs/buttons/button_5.svg)](https://cafecito.app/elmasse)  \n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"0157fe88f3acde0d6d3681026ab1ff5d5d9984ec","_id":"nextein@3.0.0-beta.6","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-VtQuebTkP7spEMLB/rePywo2CL4FWcnmuPs0BUOH5BwobY1b61BjH0AfzLt/AbnURtucrmyS3SRaFe7w/YREjw==","shasum":"d2c42577faee21e17e782f9aca2a68dd324a87c7","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.6.tgz","fileCount":44,"unpackedSize":155880,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYOpoCRA9TVsSAnZWagAAtaUP/0bvSMXo1AydBMXnjuRH\ndqKROgydm+QwyNMYO13Lu7em55i3y2eHgdKfc6wFvvyn3xLUyHJYaKeBHZlM\nROJVkxkgU4eRi4t2EqXNgXDav/tn1XYdFJjnwr4YhoNTky47oG4xr/l/GgsH\nkT/RAR4Pr4GMIGljDp8Kta7vDtKTk9ITj+jnTiyJ8lCgJtD3ey8Gn8rVViiv\nwVH/FtbjZgQXGGjsbcNHcni7lCC8CxQSWpBPRItBvjGU/xYzRaFjXQ5FL/h/\nnlxkv1K2fH9LvmuAGgKPWI6s1gHWJvTR4yrGwIBg6Gi5NdwAYZh0QlNdj63Q\nqXdbM8GwDiMmearfungeoTFsw1VsPwxzVXeyrBbSlETYl01AsvAoUCNOaFEp\nOHkX/bucMX3Qd45/LFc6VrDuu71gLa3Tp/T8eqM8pDjxPRbWB3VLxa15VAxl\nYUsoBhct6NegZlpH20CE8xLoDVGQnnxFo5S7lGq3fH+0znx5TWM57NAN4MGg\nsI/ornQFFrZ/pxYgdYyc2swrq7hw0OJV45BCfXrxvo3mAM+kJlnl0RpjM43X\n9tmUPv+TAgDAbMKUJGlTuD/itfk1SSlH+vNvXO/c8FCoP3NuaL9qqsExN/kl\nM7rExqNenKzfo/NTQdtCJchoo3U7BdljB8/lXkPd5sY5dZwL3+n3mWIQrp8P\nupvT\r\n=sAvg\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIArwd4FVuLR+a0wfAG9S3nU+g4A4W4IBl+wJh6xCdnJOAiEAojJWI0BNY1RZibA0rs0+YjDGioDahSjQjclLRcrKBMg="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.6_1600186983544_0.6187807592641306"},"_hasShrinkwrap":false},"3.0.0-beta.7":{"name":"nextein","version":"3.0.0-beta.7","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0","react":"^16.8.0","react-dom":"^16.8.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Invitame un café en cafecito.app](https://cdn.cafecito.app/imgs/buttons/button_5.svg)](https://cafecito.app/elmasse)  \n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v8.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n### Example\nSee [nextein-example](https://github.com/elmasse/nextein-example) for a working example\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"64a16735a44a3ade991688cbc677ef12e3c4830d","_id":"nextein@3.0.0-beta.7","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-Ut4GXRVsTefYVSXsMi3/4W5LOyLOSNRYaKM2GsrYmYB9W8iDygq3mdQ1e4ydSUluIKhovxXjPI0FpINlX8KYuQ==","shasum":"0fc8d09c1cb0497bbb5d8f74ea84c51b7877c2b2","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.7.tgz","fileCount":44,"unpackedSize":158215,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfZMVrCRA9TVsSAnZWagAA8i8P/iDHefyiDbEVBjEXFEC7\naecO0RTwLGYcN1ab1AOMOx8TgBZjWRSE3Q2/aiPKWmhu+UuwMrIjuOmXBMwM\n6f3gSDGeEFL/L8En8nighOZOly+DcqJ3VpKhEB081I1k6iWDfBsQVCEKpH5V\nOeDrCMziIs5Zq25l1ipZSAgsDjS9xO8W104PiLop6L6fkuJvU6Wbyoq2MlAl\nA9fvV7lOwJ/sbRWtZ6gWuaI3+bukXJNuwy+mX48L90dk/GFseZnGQgal6+U1\nAaLH0tdCu9RxjOdcrUhX7BozhPYSMEbBS4ptkJor0u9AB3+7yHz8ZtwdKbDg\ndLysFyI2v/m7VCNjv1o8cSUIY0rgVFiH+FUw14Lv4am6UGJh88BL6HhFawoT\nWnr2yQP2FDwuoL5dR2eQOaloRkgalh/9xl4v2K0h4Q1Sn2hoYU4PP3HAB7QQ\nhL+Oj46/sxJUx6KPH1IYPcqO3xiOw9NEhlDTaev3LU9xrJGZ1aNLcnZ2qJqt\nTFnacUW/K9VuDjAa/Yx+N7zu2hiiYHDECMtipQl1G7vIbvucn/CG3kYzoOAf\nJHaDPOBydljidT5d61+dpLGgK0kp9Pe82FY44JiPHW/OE0UTOV+GnzE4FixS\n6+0ea7DjPjW1ruw+fMHc2lsmuNIrcRSfGoGuAdPWjnDlkUc/nV1guwjA2Ho0\nl72y\r\n=f3jn\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDUueNDgx9ixDOgB3zmpeIAZX1VxfpIbCfRvQdzdDXGeAIgGNQlYZg5qOaexX8GYMUyC/x/nmrVS9HzFhCzYuKZ00c="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.7_1600439658991_0.6513367854734804"},"_hasShrinkwrap":false},"3.0.0-beta.8":{"name":"nextein","version":"3.0.0-beta.8","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"test":"jest","build":"taskr","release":"taskr release","prepublish":"npm run release","lint":"standard 'bin/*' 'src/**/*.js'","version":"chan release ${npm_package_version} && git add .","postinstall":"opencollective-postinstall || true"},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0","react":"^16.8.0","react-dom":"^16.8.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Invitame un café en cafecito.app](https://cdn.cafecito.app/imgs/buttons/button_5.svg)](https://cafecito.app/elmasse)  \n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"e60622505c7d6454d77cdfa25c7a3df7a9114193","_id":"nextein@3.0.0-beta.8","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-7QrO+mu9umotNh2TdmbtAummf1Ea21bsYDpjSB0geQGEW1vDHeQaxYhwjpm1LN+bw/PYs/4AaTZ8BdftNqGypQ==","shasum":"4796e103dd335af759ee43affb9f485da9ee5595","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.8.tgz","fileCount":44,"unpackedSize":159872,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfa03QCRA9TVsSAnZWagAAk4AP/0p5UI5BWZMgwF2LrMdh\nxSDINRcuy2X3YpLwfeDRH/ZMZ8iL6K7+0uEDPiltDX83e76cW3T37puvWF+v\nhD2ogK+IEOMJfpeaoTNp4lrzNc1LUK8k4UB+uHAVQqV72MlMmwY+YlyrFTDu\ntgHlOWcReYXgerZvRkJvptmJ38Gp2K6/ScETGwlXCip1dXdeIxPF7gHOT3pr\nvisigvwPSK0ZDs5wW6Vqf8TRXHtgvA6IW+QUtElxo/f6KI6D76IK9/e6CtVT\nycQ7bOFdEf6Q+b3qPFoeISdMjhKCgF1fjrAd8kDEbXxXyEA/em2D4dFS4jwe\nQkqY7ql9+7CuZn14iyOMpgu4ewR5LwshF3hpNfNX5iSN/VTG3S7AyF7kvW5Z\no1k4GHMnntN/vJ3ndRWng9dV0XWzDBng1Dv3b/HqhnRPI3Gs88mK4arLzaov\nO7QV4T1mmyw9zde2HUI3iPqs6lIF4uPMjHp/PT5hapLfnFliADfPm7Nn2Y+5\nnczJVK65MoXm79Jk3npaQQxkQCZCs0dvBUG0h1wXstFeSBIzMQE6XiUXLtKk\n5rQ7rMRbIKQKJqbT/paXR7lt2JPs4nU9rl1kNom5sTJV1xiW76JJmT9KkEEA\n08IQOVX5MEH7OzEjdqgaROVEd7KTbQGkspgRgI+LE6NuNh4hhV6GgBEC/lgV\nYaV2\r\n=GU7d\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE1K+fS/7cVGE4Cnp2HcgXbrAtmLmdmE92xTMF9J4CFRAiEAq+BL0PBThkjMo3xvVxHPBabA87BHnmfnBbrljtw5Ot4="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.8_1600867792083_0.47227069546830713"},"_hasShrinkwrap":false},"3.0.0-beta.9":{"name":"nextein","version":"3.0.0-beta.9","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublish":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0","react":"^16.8.0","react-dom":"^16.8.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Invitame un café en cafecito.app](https://cdn.cafecito.app/imgs/buttons/button_5.svg)](https://cafecito.app/elmasse)  \n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"1f5e8ff79fe0e17a2130fb39f3903a2b09696113","_id":"nextein@3.0.0-beta.9","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-ln7mvqqbZEgPCc7xfb2ax7GF7suIIIhIDlK2/JhnigZ77xXP8+RV39lV6IXE9bI94hdR36cZV2ldiPjEMr5hVA==","shasum":"26d50a3aa7250015d0fc2d234db3006f0b002134","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.9.tgz","fileCount":44,"unpackedSize":160290,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfeyW6CRA9TVsSAnZWagAAiyMP/1SSKoWAY2POe5Bth1Ko\nofQqGy6UIyShxYX32lbNwu0sdo5ZpeGkALJUyrJja4vij+DBblT67xL2/AE3\nctOspphHKq6rdCEkg2bgVyq9tlm8yzlgCaSDtPcHdTjxVsJkC9soGyte3pPQ\ngREkUUV0mSiqHDryCm5NqrWlyjfXq1H7UmE5MZ4GVe2J2n9UGigFwtgstbOW\nI4pcYFwTDirN900wGAhFFNE9UAmFXamR3oJ8k04PY9m0Wh3lAapWhwQozYH7\nFg2XWkmr31Z4T3EAVjlP7gJSA62py+r7+vhcZCLIwnvuoonFntklzWLlz1h1\nXp4mw2fgtU6ZvZsv2mHxeO4gFZKIEuAuz+In4rioO5APyVVCryaqzI+RAPdN\njfrLQM/hJME+lXDIAiLKgNcKftQ5HMLB3rms9aA38uPT6/pEv+gvYQuCmqG0\n+rtgmDqlsJQVzEztsARzWbATyfnGYG8pdRC3bN+mUi8813zWX86UbrXXO4ev\nVcwP8atpcdIDycCk47/HcIUD/la+GjJOoXaUqPppuEYh0od5XaJHMZ+oFZhj\nBp4zL2r4xOxSthEiDvay0XqqtS+IOEIFDuK50V+LSKm9CTQeMgYowksLDtA+\njehdhfkxqpkYrCl3yQhirbfCUqu6+k+ec+EAn7OK13VRChFmt7xUNVqZcH3U\n2vq+\r\n=z0Z4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGoAFPb5uQZCadBK0kbAXwvVA7SWaNv7cxr4uU04h0P1AiA1XABQpckQ7kJlsAlUN004nPu48RPkRXzpKM7Ppx4y+w=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.9_1601906105454_0.5697241622854572"},"_hasShrinkwrap":false},"3.0.0-beta.10":{"name":"nextein","version":"3.0.0-beta.10","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublish":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0","react":"^16.8.0","react-dom":"^16.8.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Invitame un café en cafecito.app](https://cdn.cafecito.app/imgs/buttons/button_5.svg)](https://cafecito.app/elmasse)  \n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"d860dee9e63514227b77a15ceff459b6e91593a9","_id":"nextein@3.0.0-beta.10","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-X3ob540fC3yjdtOH/hUdqnCkReXGYmoNTeCYIZkHL/cdMzPbdnFE+nHJ839ZKNyjbF/NjRx7HFRhqdzoe+NcRA==","shasum":"16d73aada20ac8d16cca68935a6318241b49388a","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.10.tgz","fileCount":46,"unpackedSize":165932,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfhFjtCRA9TVsSAnZWagAA+50QAImbr60Kcoq/NWmaQ1tv\n1hiAC6Mkdzb+FTpd5ReLcn99x92KDdSQeZ3khR+hmnxPt2371HtBfiemEUwP\nK33xEpZoWFu8gTdC9T+Enp6q7rLaM9ZOZ1ek0AyAAJpCW875QBrR6GHUuQLk\nd57QkyyTfr2UKu3Z58QGTPZdC6nIgpYxFeW/pnj4tov3Z2oGmA2z7AxEbyzS\noNQj0BF9wZ4zg7Z8pM+6V/qGkDnZ/hW+jTmlZBsJYbXIq3qR4QZxr/jY8vVR\nc2dTcKkBk5SpKAi9uSPs+ssyR6uTR4YltMl+HFzMM09lxK5dc4EubsKZpD13\np3sQ2+YFVP1P9YOSFFky9LnWfF2/G4x6Akcy4Lp/a7tozojHe0qt+mPOQLwY\no6IWq4EkBCmXboJMPwa449xSyWOdmkNVLdMvcY+eM8kFRvvxMSCOX99LVTpP\njmoUlFvu3S2pjeRFngB4kaaf86Q/nAghkL+ZaoBSt+z1Wbs5wbWIU+w9fAzU\nC29oAMe299OBG/2BJWlRu03eV3CwIwKVNdhlR6Eyt8mPTvyHxRyvlVSF9nVh\nomsxoc0G7ARtHdxs4x8Vc/HRDWfpyh3vuxoaHA5LkxIVUaSh6NslzNQ1RGF6\nMp/NSl/7JsfHcAZ7fgE23W1cEyfSNoM4WNNJuD9EFCxgebDFJ4Fz9/vle3zY\nftEq\r\n=+k/7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC/ItD7Pqj7aVWiXeCW2GiSbhd1CMkGW83JbzbXs3bmwgIhAN21dpzxztp0jpuewcVIv3S6MzRiHwmBhaMc2lDKtI7C"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.10_1602509037343_0.4238222055048444"},"_hasShrinkwrap":false},"3.0.0-beta.11":{"name":"nextein","version":"3.0.0-beta.11","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublish":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0","react":"^16.8.0","react-dom":"^16.8.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Invitame un café en cafecito.app](https://cdn.cafecito.app/imgs/buttons/button_5.svg)](https://cafecito.app/elmasse)  \n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `prefix`: `{String}` Prefix to use for the generated React elements. Optional. Default: `'entry-'`\n- `component`: `{String|React.Component}`\tThe component used for the root node. Either a string to use or a React Component.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugin (nextein-plugin-markdown)\n\nThe default plugin will source the posts using a configurable set of options:\n\n- `extension`: Default to `md`\n- `entriesDir`: Default to `['posts']`\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nBoth types are just async functions. You have to export a `source` and/or `transform` method from you plugin main module:\n\n```js\n// file: ./plugins/my-plugin\n\n/* source plugin  (options) => post[]  */\nmodule.exports.source = async (options) => { /* return your posts */ }\n\n/* transform plugin (options, post[]) =>  post[] */\nmodule.export.transform = async (options, posts) => { /* return your posts */ }\n\n```\n\nThen in the `next.config.js` file you can define your plugin with options as follows. The same `options` object will be passed to both `source` and `transform` methods.\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['./plugins/my-plugin', { awesome: true }]\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"5829b81245e56e676a7017b62eb086ac1a14bbd3","_id":"nextein@3.0.0-beta.11","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-bMvYgvLLy49FImh6lK1a3hFVUaA1YJcibo8GsMYBfT/lH4YsKWO957pwrREFzNILFELEMbd+kX1ZfwL4G53wkw==","shasum":"c82a2a239e6f83f52fd711aee13d8a60ea5300cd","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.11.tgz","fileCount":44,"unpackedSize":160328,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfhZ3NCRA9TVsSAnZWagAArgIQAI84uVsygcR+lbew2S/n\nTWAwZnP+xooMqTCPvNAbRzRJsD5MC+XE1d1jlXgG4bZuse37CPFTCw5ZlbCI\noZorODf+31tMHErL8HLO26uCzupmyNXrlbkkdjM1VQMj5gNp+IM49AQ/0P0Z\ntlVV5m7p/fnhxiE+6Uy4Lt+dzakhOFdZ91F9byh01VGCYkOLGYq/pkRT2BC2\nnxCBUm4M9v1/Cx4GaeZ4KsCUWLl8TpEH9GGSb1UtGB3yuuJ+mh+TAAsj78Ua\n1G6/QiB736/ZVw4zD7KnmgxzNA3GNYy4UiO59MIvqYurQNTrOi4w4eO2cg57\nyiClW50FgSsjVwU89yJFkmyXL6prhLZRazeBqSVT0igPMmOcYwDa5W8kYrSY\nEug141uOFy4HpveXq+RkWrCjs1IaBZPt9Toc2MwKZ3TCVASyAv2lztnsegrM\njfvXUYHRi8xSmotzssalzzLhtvAsJRuo2eMQNvKjFTwXvW/dgksZgkF7g1Vh\nB8EnsSWVrJ6clguw8qgOhR2MNFtgLG2Lylc5ZU1wQNpqM5uxKIHeHeccyT29\nf827a/V7dkZ/IaRpN6Ca22G/i6DHd3+lOT8bLftlRCpYc8y8lZvLHGI1a/E4\nB8KRrYxULGi9L770VYfish6QOTrBy3MUQLMAf04ffZciNKBNMTPJ9AiB76VD\nQocv\r\n=7Thl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDb2BQhqzxB4BG22xKk9P6yZFb2kLsY6QS4dGYUT6JCOAiEAkGQpvN9K2S2O8zsoorFjCEkkpF23n7O0FlyFJ6GE1Is="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.11_1602592205349_0.8916692398599464"},"_hasShrinkwrap":false},"3.0.0-beta.12":{"name":"nextein","version":"3.0.0-beta.12","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0","react":"^16.8.0","react-dom":"^16.8.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Invitame un café en cafecito.app](https://cdn.cafecito.app/imgs/buttons/button_5.svg)](https://cafecito.app/elmasse)  \n[![Financial Contributors on Open Collective](https://opencollective.com/nextein/all/badge.svg?label=financial+contributors)](https://opencollective.com/nextein)  \n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n## [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import { Content } from 'nextein/post'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost, { Content } from 'nextein/post'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, {inCategory} from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n} )\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nexport default withPost( ({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n} )\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` instead with the exact same parameters as `next/link`. This component wraps the `next/link` one to simplify creating a _Link_ for a given post object. `next/link` will work out of the box.\n When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `raw` is markdown content of the post\n- `content` is a HAST representation of post content \n\n```js\n\n{ data, raw } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\n\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      ['nextein-plugin-markdown', { entriesDir: ['_posts'] }]\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\n// TODO - Add definitions here.\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"8497ba8078f1b3153fd37592f6a9c8a71dab50c4","_id":"nextein@3.0.0-beta.12","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-0/d4V5tRrcSzzDscLoTNFjkTZm1pX9mUgBBgarJtynAzhVBX7Xe9W/vzbvnhk/vEC2dV/qDM7Y/3X8hn7P1iPA==","shasum":"ca1acf29579d14fc297f640f0020a3e3a7ffbd08","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.12.tgz","fileCount":44,"unpackedSize":160204,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfhuiDCRA9TVsSAnZWagAAWTsP+wUDiBTy3aGXcUJILQ8g\nb0c1C6doqbBJFTCtkK/LmAp6B3yoEQjjQhDhKwTmUGSIegm0orSgND+6KtGf\n/yzNj5VFtVmS96qQjoSp1JqxecZGJuqCa47plyQzrfMDsxH8f46umoFqK6bH\nFCQ+AFmTzWAdZ3rdGPqglGlSE53O3G8Gzu0MYb/mVZxtGn6qnkV99XgNONL+\nTgoagmPEZoG+y22feyGtM9RfiHcV5/9OhEpv5ipmXto6hEJyY06DAvf1N/lh\nLNnQXgrRwAz35N6rLh38DFVlQjxnJNwOmM0r63OGI8B64QAgyU8rjNz+qExh\n17i8ENJpm6y4ej3qiNQJxHJ+T2Z2mfri7xXMxHyogFWmsMNCaZK/yEGcfj5m\nRLH9Qn6ek+4G5jOmO/M0RvEgIdAuq/aaZfZKXOgV8qhYdfnUL0A3wxuXssha\n1+bnt1yhctN2S/ViKrQGJSKBAoD3vy0TYYQPdsHI1HccJe8kGU85KBJbSvEu\nVX4ZycGcAj3qsT+NO905MPVV/WPHcE6oAcTGpImshMCGrapD2J/p3cIulucT\nsFjQO33nsncNFR98GwVZI36fEzIjBwqN/hl9SvmHyXCbuT42tGX+c0rLktHB\n5/YdbYkHZcYZ0i/Xn8UIFW/K+3GT3XtQNQmhaDxJ2bTDDI7Z8/yDSb7LLvgm\nVDVj\r\n=vVms\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAbkzDcPxFgOtYbb4hSFWkf/WqHRHu2M/s7bn4t728jOAiAJ6AV4BfQCzbsgrYubESm/sbaj9pmlxICmRf597gyI2g=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.12_1602676866978_0.9424645642441676"},"_hasShrinkwrap":false},"3.0.0-beta.13":{"name":"nextein","version":"3.0.0-beta.13","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0","react":"^16.8.0","react-dom":"^16.8.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"faaf8f9865bbe63d438dec89dc85933bf2d1254f","_id":"nextein@3.0.0-beta.13","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-Bwan4Ab/CZ8H4THc+aoD8cT12kFbnnKy+FpfZFZOHJb92rFrqugppRa+w0SP9dH+f0e23gqG+DpreQze7H+m9w==","shasum":"1cd6162e7661a47481211557245ef4275e49b049","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.13.tgz","fileCount":48,"unpackedSize":167958,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfiJTjCRA9TVsSAnZWagAAQg0P/0q4QgJ4PUUKv1nhNPN4\neP1x8B9xVikghgcD7mjnmmsaMBYi1ZLr9s4QxdJpd+FCsiafFZ94qG2q6k2V\nYLSytkpLVfXwb/Re9VYuUYlIMNA52EMeLEQunFTxT0NocKgqaXrWD6kMQ/1F\nIAOIFOZXg1Qy4JC/sNUojcyW33u+lN2RApM5rdwNbk1SvI748JILQgn5LYqF\nsXQk0bf2UwDJS4wI7+Zoes3Z/myFH3O/u3yWoKkjDCDYkijwVdC0+EcqezLj\npc7yoGIWeAfklxFx5GNfgsblhkaTkIKZXdMOgtcMx+h6Eq5IPvhsR7WyKTIS\nS1xb4hCI1B7EyqWE96mcKTyDHBixsKA33+slgEH2d/u+iVuysujqAwcojSWF\nL/1FM6w1DHPm1zTeWYmR/Ofjpw47l4LVtNIpMCuC4llMaix68V18uwcm07YE\nNRXhnikFt5cYmc1tJ5Y8hLtUw1RwBcoXTPV1sxI0AZTiNyy4L+KNv3iyigIp\n1bbrrfoecCzlmOxcHKkjIHAk3Ln+tCa3jutXylw4BPwlCvOLeD3v5Ra2qDUl\nmh0IJDFK/uEVKLl7XB4mFz4ocDFkC+7+gz44LGFXyJXztnOXcVRjg4JlgbKR\na1od6ehWNz5Jjkv3sP4tQtePCATQ2E+bAo7qRXd122p+kcrvsbqzl2kYQBuD\nNj6J\r\n=w3it\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCM7lPd6zQuhtwjE3BZ9T5Bpyx3wWblQWdoZdsyokEU1wIgMEl04j+2msptoeOyWwVIvrPM4rs4XXZmuThMt1cxYWI="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.13_1602786531246_0.9606323810994777"},"_hasShrinkwrap":false},"3.0.0-beta.14":{"name":"nextein","version":"3.0.0-beta.14","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0","react":"^16.8.0","react-dom":"^16.8.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"dc07b9fb91a991c88896ab4c378837e544cb8a03","_id":"nextein@3.0.0-beta.14","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-2LFBWaUOh6gMOhprHEMzdPaoqG454XIylfpBXF1uy+9/VKvT3AgRLubzEvfjZfhHltlygsDRwvehJl42seaBVQ==","shasum":"e163be9a6d71abfbdb4a7c4335248ae3e4977683","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.14.tgz","fileCount":48,"unpackedSize":168072,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfiKTwCRA9TVsSAnZWagAAcu4P/3Owa6J+cSdC5hdpbHEv\nbjUZR0jUMNE/4sZcHRiaGBSy05IYFSIzXnX2mwhCrsFL9GzwVWIxC25fPrLj\ny6CsGpQDF8RMQTIg8uo9uV1gpnAHPYiplTfH+ET5rmNOljxCphpJ5i2ZUG4g\n3XO0CgzXdO1N1ux05n7rb0/ehepOnIPGNkvusJUVUM5VtBi/U0sgiYxf+IfK\nQh2BlAZEzxDO9gBVmK65GcM+aaEWwQiHLYlubs/F6AAfFWfRLiJalexoMViB\nGwCgdOr/MBzj2WOGGFxnWD/WFRfbmqn8onMFN7dh0WtRL+UceVMg7SuP8dW5\nWPx8mRCuLb5u8euxspWivIO4fwWFDuV+MtR+tCQF47ffqMNJBXHokpidkZ7e\nmntK+YqvS2SZEwQsbQZ28WipZqH97RB2PSTDF0Lae3dgYeeJKYRhQzCMHG4T\nMBAw6JBk80o/Bk/91SjTs6i6GekQSE1uWncN/WYAB/axsgmmhgtLbVTQUp58\nLcTNoS9hIRc+4oC/w6OYe4MIxAaUpseB7LDAonvFAsHUWt8vbVFKVObD+bfP\njjh5soejQvDNNEYI3Sv0S8Z8E9cLM8my2xol+MYDcQPwECL3cfxh1OwUdKPV\nTIZJaM9qJaHoz8a5/8o6X/yffdJbR9ggCYrQKAWcrQIU+7FMZS5bt+bLgowz\n/Vcq\r\n=Y2wZ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD4JQs6d+okHuKLb028brKtJU2+1KCst55W/jx3GVpZ3gIgeddL3tr5DfUEPTExMB8IC8xr+hWzJ0uBKDNFRoEEnvw="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.14_1602790640380_0.8164932803690426"},"_hasShrinkwrap":false},"3.0.0-beta.15":{"name":"nextein","version":"3.0.0-beta.15","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0","react":"^16.8.0","react-dom":"^16.8.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"6a78d1a70c93a635d54892f8e14beb00a0842e90","_id":"nextein@3.0.0-beta.15","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-tjmFvaDn1v+vE4vNb8eYF/Fgv+sEOr8WwJEk65gl9Ocifg1FI/fhyrnvsK3Gql7Ltb4IDFl++GCL6w1IWeINnA==","shasum":"8bdd5513d52f880b33157723a622932cae573401","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.15.tgz","fileCount":48,"unpackedSize":168050,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfiYawCRA9TVsSAnZWagAAQF8P/AxcL/6rEeUmNKPovqpS\nWBJjt97xv0TStJKfkgcvRIZEQjvIYTdEazVlr2NSs7ZUFMJ4MpazPelPZoVY\nmKJ9Zryjor34gRCKAMKrheKuO1yIkpqnDYFQfHkqfYpbiB3zsQwDAVDSR+kG\nf/Ul6TJFx7WrSUmnlMpbZh6j9al10UUfEwGTHceFO0fw5loZr29bII5zXGAo\nTkHM+opsqZpLSWXHtElQzYdIird1NGyao6xY2Lxrdk+HAhIUQbF3I+jot4KB\nblbjlNyN8v+ldlu/XS2l5AORO2YVgn0iUXOdLOojxDMKW0+Pgj+3HgNH5xkY\npxVYfFyFllglfMKrD9+GJswGwmtgy2bAE6SooEMUVKNolSkr6pgTjbPjbpNC\nwlTOg0Exieek97Dlo5pM3Fz1MXAFqhG8YeAJN3nt3siN5jmm3+JhLKRdR/QM\nrQRLi8YV+jc11i/9gtlfGvxccxU70cb0FmjWPmj5P8DvVkpXig92V7fm00de\ny950JEA3pJWKMk1zecuiKtICYwGbiKpQGC74YePtJzXmeV81ayhT+CHO5amg\nS0qMW5BHYVL8517F7jwlzU69KmGJ7tzbBvcutCx7vfbky8iqqfRQYbgwUWMD\nslaA41SMfC+hmB3Mozv8+F7ik9eH7Vyp/VYoX4wW3sdK/n8VywrKWa9MGb8+\ncjzn\r\n=F7Dv\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICLjp4zJS1InGVjFOUOBBvZDUX6eY18uAy/myacUW+qBAiApdV28SV13GBS6DU1iMUT1xIpwJJRGyBdY6n9p1sALXQ=="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.15_1602848432495_0.31826393305891476"},"_hasShrinkwrap":false},"3.0.0-beta.16":{"name":"nextein","version":"3.0.0-beta.16","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0","react":"^16.8.0","react-dom":"^16.8.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy, inCategory } from 'nextein/posts'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"1c7107a4f2351c2866d4b9c790c300ec00d74742","_id":"nextein@3.0.0-beta.16","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-wgyXlrxHzMl/1vyJLBrnFOwbeq/4NDaGUvGkmFfRWL9diQnU4HVQo9aWrt05zSO+RcqHJNgX3XHfUVGCrGmsoQ==","shasum":"f90c1a4d6749aa5eaed8b462850ff98ca660d45c","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.16.tgz","fileCount":48,"unpackedSize":168390,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfiarfCRA9TVsSAnZWagAAmjUQAJSVb0X8RQ3TspyqNY/K\ngY6HU36YCDpOSddNSUrGIq1S5oCaPL0o9x9AVs9L9aGLVtJXyKYPEnddvCb+\n2m3ICsyfwZsZUxuBuuIA9NlQqt/QwqfHdHFKxrrmCe9+QmIzyykBk1V/QHRX\nMyME/7ixNYSWbZ3M73VjhBJXr555mCKBfQDE+Cqt26eP9j1WXMNjcws2Oa2C\njJsTCuKkjq/domVwOOMCqCBlISQoa92gQKxsnbyJEJOkFru9Yr8c97Dv+rUa\nfiJcB7366svEEr8BQL41GA1kLaNPv1mhAask1+xY6NLVniL49twVVuLI9gsK\nX6L8UPEZ8Sk6hCf3JTxLHeoyqaSI+pRKaLWVfIxj90zfm0XOeG55TQTBLn6X\nE23Lwe693jmgS0g65OHq09neChSPhOaz/vritmfClnr0gZnq+/PqA70sm6TP\nMvGbpHErHizu6fb2tWedB0J9K50jg1m4VOfxiy/2mF9HrAvSZ3rlUOA9UZCI\nPzJKaztxFzBXQl7AuUWdnU9RC3Ydp4GxnZXUs0OCr+dwhbCTLqZnnUqsfBbv\n09YEmRW8R+FyiWdjMDI6+f3QAs1lC39gswFG3ZMcab/9TOU1T8fiE8M8r+j5\n+Y1ODG5lx19G4TJdcLcRPtuCG4R7NpuNnQ4bS+xgBGDcEWuwB+gn3N8eoDJ0\ne/5T\r\n=zFW2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFsnMvNCBsHFPPVLI9QKp6eOYBn+NTJbd1r8/pLkGV2hAiEA7t27wJWfyfjeuGqfe2oJh9G2EysJEhyrD3mwqhxV2q8="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.16_1602857694704_0.671325709140234"},"_hasShrinkwrap":false},"3.0.0-beta.17":{"name":"nextein","version":"3.0.0-beta.17","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0","react":"^16.8.0","react-dom":"^16.8.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"9.3.6","react":"^16.8.1","react-dom":"^16.8.1","react-test-renderer":"^16.8.1","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy } from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `fetcher` \n\nStatus: **Experimental**\n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths) can be used with this new experimental feature.\n\n**NOTE**: For now, all posts rendered in a dynamic route require to have `page: false`. \n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n#### Caveats\n\n- Post are required to be marked with `page: false`.\n- No fast refresh for post changes.\n- The `nextein` Link won't work since page is set to false.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"d76ca21fb94509bae45fc95e78fee5c50c7347b7","_id":"nextein@3.0.0-beta.17","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-/r4b++U4iOTdLvzv4Apjq0ieVtQ+UGbJj0tzagCPff6DpqP1/W2loTNfX2ImuBFagu2w3lCXQ58cGJqaX8V5Vw==","shasum":"ef4f347f058060ec8a4c357659db3eff6bb5932d","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.17.tgz","fileCount":48,"unpackedSize":170473,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfkFyUCRA9TVsSAnZWagAAoJUP/R6haEiNR3+kZzdGf772\nJvlbXhcv2wtYpjsWSByNtb+p2+tQoMIMZYsjfPSw/EUGUu82TEIQ+COagyhs\nwR2eYGJbSSXEKBsckeJEm+9BjJJD2iqdM4un2cS086lq6VswORzZQfql/84I\nL0P2L5dRN5xmw9+fJl1hLxVn0mEMABYl9zf8n+Hq1EY5v/TwJtwmrFyn8xZE\nBCDbZUnxGNliTvee8PldoWIuQyo50UcG4k8g+Jr3a+2yTWxMqsO7n0FIbvEl\nlaOFiiX4AdNabe8osKhKkimLW4kWEoo6zCZln7WsPhkldcL1KOzVx04tKELO\nWziaFWm0lgRemCCG97Inzu5p7OLFdiQmtoFUNpkIiBm+Hq0BEYX9ImUJU3++\nNeaQqkGa1k2rf0XFvsLQCW+A9ph8ztOjcfOKrp34vY/a+6S3H8EjwirlGhqO\n57c3GLOkJov+yypNYNDX78uQ5aTUJ/HBLkoAGOoYQHxiTqKyVVMSWc3YAm38\n4EZNaDXsffCx4w9jPtpU38rWOnFA8aPKjXi7Cho06AQKKyXJiDdGHEH0gVx4\nxl3bfOTCrS/WhDuN1pFjceO+LPm3vK9ExNYtS0nF/PCoNidvXljbF/xPSMWV\nQgIYTolSeYRVPFn70EP1bb/UZkOOSyiHLVFyVFbgb0hVVn71VOK0btMBUd0T\nFmgS\r\n=wWfj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGmEos+ruQAr9D3rrnRyaqW0tKsBPOn6VApYSLhNrOzQAiEA95ds5I20PVO9qywAxYi0f1jgc1AXSHHghJ+g8r395vw="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.17_1603296404056_0.947235863719847"},"_hasShrinkwrap":false},"3.0.0-beta.18":{"name":"nextein","version":"3.0.0-beta.18","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^10.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy } from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `fetcher` \n\nStatus: **Experimental**\n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths) can be used with this new experimental feature.\n\n**NOTE**: For now, all posts rendered in a dynamic route require to have `page: false`. \n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n#### Caveats\n\n- Post are required to be marked with `page: false`.\n- No fast refresh for post changes.\n- The `nextein` Link won't work since page is set to false.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"0ccee2495a5754f0f06b70925c3c21da83554461","_id":"nextein@3.0.0-beta.18","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-+QVW3wy7yiJFTGmVSAPnIk3PrSUkE7az+/GdTl4Z4uYAemCcwRoHUqr1/vAosyeH5jNq6ylix9QnM756xaufVQ==","shasum":"43558ebad65d967e80234e282b9aed9a6fb42492","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.18.tgz","fileCount":48,"unpackedSize":170508,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfmIKHCRA9TVsSAnZWagAAlHgQAJqSfiH6tpFFF/56pFH8\nsm+3evRxUAbHp8ZIcj/T2G3f0bkyq1xK/M3A4eQ2kAttUT9v/lAKkfzjvUf/\nAjVP0CykfyWyQ3cu9b35a1YefWJFY1syDb6SDL+EvFi8/OA2YIZ9fXxXUNix\nC5DZp34q13WYulBsUd7xH2HSwW1ZQJnt+VzCPtpaaiNe3P8CGCXYSghgTMOP\ner/nF97YOBrKpKKEnU8ynWVEidiJfhUJDXXxyGs66vquHbh3tTtCgjHDdRWh\nw4BRBDIURJ1IZQNisfZGFqkZqIK0tL8UqEhxXfdAVtfSTM3qvI6y33nt1yyw\nH5IjCsMErBXrLzfUgYhWXe6lAAKQdNZQIJskt0NBlQQxlv2aLowunmgFk0Y7\n82B59UBaVKuOMKNiwo42h+LHOT6FWkwIGLvJABrTeJC1FZ41JAj5y/cf15JV\nvdM1FsrN05l1KaWRQX4MdM0CffD3NeQsgFaR3CWNZVD3CPkMOnGyacU5KVR5\nP5FlEA/bvdo2DY+xpG2r65qlF4thE+Q5d935mgVNd8k5/tMVF44ukr6zJd1b\nkXjDMCpwrAg8Ffpb8ttwVFXGah4Wesmldfp1JC5MuRi3lQXlvHbNT4nhwap7\nG99pB9ZpKHzyz5R6FLU9e0zH/jamtO5R6ftv1fuKTvFnz8O4UwuDDoBUSbZC\nSl/w\r\n=ANd2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDLEgQwHei0NYtUsDb9UCXjyayi9SmH5AGQwisx5Cqe+gIhAKL/kTJdpZ6DKsO2kfSu+Q9LN02ou1xJDycgZiNJZtPQ"}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.18_1603830406688_0.9912704975876245"},"_hasShrinkwrap":false},"3.0.0-beta.19":{"name":"nextein","version":"3.0.0-beta.19","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^10.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy } from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `fetcher` \n\nStatus: **Experimental**\n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths) can be used with this new experimental feature.\n\n**NOTE**: For now, all posts rendered in a dynamic route require to have `page: false`. \n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n#### Caveats\n\n- Post are required to be marked with `page: false`.\n- No fast refresh for post changes.\n- The `nextein` Link won't work since page is set to false.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"4b1c38d8f9d8c9bb0a37f0b11fb6259e3e5e0e1b","_id":"nextein@3.0.0-beta.19","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-nbFB2YZHK1rz52krLg2Om+eIiAOLekt+XZJDRi6V6SYT13wiIXyqCYv0s4CEiS0312YDayCf9wWPjcvCfD5pjg==","shasum":"99928afa80bee1268b728a6e37892d8a25cfea0e","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.19.tgz","fileCount":48,"unpackedSize":170379,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfnBiYCRA9TVsSAnZWagAAzxoP/ji7Kf5gHU9MUfIcqJPG\neJUuUlnA/+VTo3BTvTO7/x7m7nB7qr3l7quuI1D4Eg2CdE6NfbcycWvvB+bZ\nx9C1tAtpODjBKCV/e2lp4uZdgsZyoTx01Dm+kg0akgheCLkrLFXywQ9qb5Or\n2h97rfH9Xnt51EUEJaGELGb6SFXXnTtTK82ktUQ8/ZlGZdcMMFzVFMblM7fM\nM+pvkDyAlYp1q1VJq1yc3qoED4ZQF07rnZ1LDhvYtMQ5DrqtvJAXz5EdPEOa\nu9Dt6VbRgCPCge0JIFu/2Exo3oZrcjK3ylNAIW6hR6zKWvtre/yuHsDSwTLS\nUxygFkcApA38XKDNZO7aML/AC0GEE5mtcfgfTO1HJ1O5k6fVduTL7BhXah9U\norRp+LweUhy7V5LXB2JpHv7MWcTmKBmTA5mT/5B0AH62x1sZnpHUGf0EoqeM\nLjVXE2h/QRyDWy8Sfui6jwDMpMVIlCnND40oB2vs1wlSs8FQJfLgse+8Obz7\nkgB3J0mDh3jgnE78NeLis0lT16YTNpc7OhNjyCgH067VWWjm7WdVMB9JuSQ0\nyoddnD7R1yw/bb8WWLQ+FyEMRCDZqef40MXvNkyy7WubUUjSQtAhdDi6pe8m\nSVQ237qaVFChould7ZFr0omb4W/KYfOl5hQK+VHXqxMSFy/Sb363xrRztBOY\nokHg\r\n=4BQf\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCLUI/rKb2EMvUuDQROeLb9iQS0kGV7UzYPC1pkeO7zAwIgeoM/6HvCuYxChOj1BXeWwGIwPVspCQr+ycGvr2LI9Hg="}]},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.19_1604065432213_0.45136499530148577"},"_hasShrinkwrap":false},"3.0.0-beta.20":{"name":"nextein","version":"3.0.0-beta.20","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^10.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy } from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `fetcher` \n\nStatus: **Experimental**\n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths) can be used with this new experimental feature.\n\n**NOTE**: For now, all posts rendered in a dynamic route require to have `page: false`. \n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n#### Caveats\n\n- Post are required to be marked with `page: false`.\n- No fast refresh for post changes.\n- The `nextein` Link won't work since page is set to false.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"32120f8f6c883c4ea3d9fc9c498999e2322a4ef0","_id":"nextein@3.0.0-beta.20","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-o2FkPUzXSKtplvE4T31Lz+CDaQBP0WPGt92moivbamYWzGVLctJc2Gwc8+fWWsw2sQPHYItfHewaU7I9uhtoVw==","shasum":"b7f010156b2da07ccd9327109aac720ec1895ee1","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.20.tgz","fileCount":48,"unpackedSize":171505,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfoZTyCRA9TVsSAnZWagAAUDsP/1V/zH4hRUiGDLorO7wf\n8zZWtubuNIyhaEbWYqsx9Lp4jcc3CggJh8oMSWnkiqiJSsZ3kH7f9Ltbbvn4\n16JzP2Vlsooe3GR1AD5p0jozJ7sQLo1iZUy9KNRYnE9tnBZrRLlMtG96Y3Gd\nC1wuIJ1b/SmEEs6VEpufGgozXkx5/60vGS3Ak+GPY0Kg6WNNT7lF6FTT7Zuk\naerFBNJurjHMbKcWsWRo6kKwAFmtM0r8qf+2/iOJJzZqNqUBYhnlO2bJLI4z\np71/BnfRduty9XqZZlx2wvJyaTnJB5vJno7LDtjDZdL7OLC88IyIUrhV8awL\ndSIgpLjA7UveiR2snBMOIO5HTnat//GPmo6gUcpX9UF5VhmhcCZUuxk9NWxy\nfPnDXzadlTbSiDoF3EGvBIFl4c4ZOJlf/jB4W5Bg6dkKIoBdNpDsfVBiyXAh\nlomLF8uCiVcKJPTOhOfwCyz1Aa2usOs6yHBzqog5gi5zB0c8DDLthPXNPdmh\nB2rbvRxB3qAW06xMgf1XSaaYM1ea6q//BKBBBgRd5KYXhzTpemKi3UVB+94S\ne6icsTCxS4YsLHvWPsOW/ctaDkt1Egl5u2WGy3afkDTL4KbJzMu8BKTPkMCd\nC9opbwkrdbjtpInNUTTBvUPbdgl/QXgzfs3LcX4e3wxBBWkZWckv3KE1rVgC\nTsJh\r\n=0xtT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCD8CiydJhMZEYWHm0Znd+pmyz2j6MJlKooJYtsM4c40AIgaR8iyi0u28qQRDjmdfzPLqdm5s3zpTXxikejho+uwaM="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.20_1604424945676_0.4216901298990232"},"_hasShrinkwrap":false},"3.0.0-beta.21":{"name":"nextein","version":"3.0.0-beta.21","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^10.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy } from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `fetcher` \n\nStatus: **Experimental**\n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths) can be used with this new experimental feature.\n\n**NOTE**: For now, all posts rendered in a dynamic route require to have `page: false`. \n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n#### Caveats\n\n- Post are required to be marked with `page: false`.\n- No fast refresh for post changes.\n- The `nextein` Link won't work since page is set to false.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"d4493cc5b594376bdef74f643578e79c793287ff","_id":"nextein@3.0.0-beta.21","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-+lKqW07HbKCFzQEzocecpduh1qQIcZMQemQaaCuFOZwzHui19DgEaVr03Fm7en8HiH5JdZlAUYfiBpquu7fSzA==","shasum":"af6381347e2a618eb2dce2ec987f7872f6a6844f","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.21.tgz","fileCount":48,"unpackedSize":171259,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfopeFCRA9TVsSAnZWagAA66IQAJqjUUtKKhf5Orsz+1X/\nAf11wQ4OYGbvbY0S+PUbgZlVoHC1JY2UGwQUe7Em4xk2Euk8cqmWDZLkww5Y\nh//nD7zppJtSBSyro6/KXescWB7Vo9XFvTUAf21UbQHM0XwBNs+daIkQsKEW\nXTk1JgoemcY0ofM/xqhZ0I/NNOjN3ndbAl6pi3QZRPV3ZCIGEGM+g/D5F33h\nA5Iq3iYxpX5uzsY5zLHfk/dwZ2atOrWH/uB8fM8PhIrGavKRAENEDU2DgF7A\n/RuRQfx1p46KH8mxR9B5jtOXibaH3ZKY3pamG8kZuMc35b4KfKlxhMLboOMJ\nCegOBNwo7J7Oes9/++IuItX3xaVwWNqcwXv3NImGQq1+/JmT5/3IP4lx6g7x\nE0Ku+X2IYSNlIWvdmT3hiUgTYIDr5xQp0nhAisj8D0OSNp1HSWBaxjOXd8Zk\nLi85NE5xVbmCzaYrzTJvJ2sFXlfIH8OepSHFjOxjdpCKdfSV6dWocowNNA3g\nHAWf4Lg2SpolAyR9um6LcPrKCVF/K0LWgQV2qBkPbP9HizpHlquK8B0w0YU8\naMKN41f2ooW8xkynELMJJqZ+rCEP+kxHp4+VbpZZOXCuin9KM5GJhMdOZ7CC\n2kBYFerP0IJbHHdAYPgTODGVZPmJL0ltIxmXfZwuzmfvGbBAV2MfBlVAQg+B\nz+XQ\r\n=Ia7I\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCRfNHKQ94p6m1J8CskMuHy/Ldauui8Wsc6OtwvKanFRwIgCTZHYd18CZ2+1cWVpf3hRQ3GiHmmcPx4OczU1r1PQW8="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.21_1604491140917_0.2828382256818176"},"_hasShrinkwrap":false},"3.0.0-beta.22":{"name":"nextein","version":"3.0.0-beta.22","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^10.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy } from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `fetcher` \n\nStatus: **Experimental**\n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths) can be used with this new experimental feature.\n\n**NOTE**: For now, all posts rendered in a dynamic route require to have `page: false`. \n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n#### Caveats\n\n- Post are required to be marked with `page: false`.\n- No fast refresh for post changes.\n- The `nextein` Link won't work since page is set to false.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"6caaf5de1ad3fb791fec8434346172324c32b559","_id":"nextein@3.0.0-beta.22","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-zOMjrw3yhnrI9ES8WWwEKZVaU4kYSsZuqd64jQLXG6vtr5C2M6vp6Wb1+Y8GUN8z0I61phoXm8j2h+dWTznmvQ==","shasum":"cde7ee6c1b8f9026a362a50061a39b8119cfcdb5","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.22.tgz","fileCount":48,"unpackedSize":171330,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfpHa5CRA9TVsSAnZWagAA0p8P/AuB7Vpmn1vbPn7jR48o\nCDW/Aj2G63MB+Shd925Sw13lfoiHLjkjxe36Z9V5vP+Yfo1nhHTY5omgiW40\n5/2pfi54SyhUEnjqTA8JmBcatlVu6qqV1qFrg2JaDIrdzCbQT/rAbO1dQCV2\nBbkdWl5ildXCsp4fJdWaM0dgRsdBEVRTtnJFpiHuEgWlyfphZk7IJgQ6XdOg\n4Rqucc95hZmJ0s5I5W7unvqyqtkwzFTLIm1vVpQ9PRuvAtoaA5CMcKcm5mUk\natPu4OiD7/EUU2uqxrUmjqsrC+uSJTvVKhnluDkzJt5aGnAzUQkTWn4sfyFM\neyPxawqrv+3fS+Cl8OoOtaztgOMsXcAN44hWon7wHm7eOazor7rykWMqnRd9\niXUGy54kDG2xtHO6Euml8B0X02QpWoE86M5xTU+m5v7YpZKkPITKoOF5coHu\nhwFwQT6WNyQTRdvIV2A6IoY17BDDhk0IH2h8APWfWovuUa8sEoLtzhJyPnqS\n8R4aXirsMHSj7w99Kp2KTBv0OQ9vGQZH8xWBnA8KTmwz5UVAG4mVa+FVmtrN\ni2PdgqcuRhvBNdFuA4IL/kz0PRfsb3+wqUAmz5Yg1o3pmYRFkfdjgOrK6R4p\nKJuW9dOWWf+q9E/qhXJVj4wzyiMys9L/UGxyz80roLAgZ5w6tHpbeqSo31mn\nPgBr\r\n=FJ0v\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCy1HI5rERC3GiSKVR/+c9bP3kV3DHHckn2TK64O72r8QIhAM1wJ80KWa5fabpHwP8XYaI5f+n9Ll78YZZgzae97HvE"}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.22_1604613816458_0.5572831099402831"},"_hasShrinkwrap":false},"3.0.0-beta.23":{"name":"nextein","version":"3.0.0-beta.23","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^10.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy } from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `fetcher` \n\nStatus: **Experimental**\n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths) can be used with this new experimental feature.\n\n**NOTE**: For now, all posts rendered in a dynamic route require to have `page: false`. \n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n#### Caveats\n\n- Post are required to be marked with `page: false`.\n- No fast refresh for post changes.\n- The `nextein` Link won't work since page is set to false.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"655c5edb65b8299bc47a0bbb51884727dca7f7fc","_id":"nextein@3.0.0-beta.23","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-bPscq7x4ZHMPIIz5xFAdlawqaUM/QFInTlcEZvqzEhaC/us9C+9H3cJz8xvJnoLwFyVHyEano/YkL+JMeM9O/Q==","shasum":"297f8e5834fd11ed0300952ae420241d1872cc3a","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.23.tgz","fileCount":48,"unpackedSize":171791,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfq8VhCRA9TVsSAnZWagAAJt8P/2XqAvX7CPBPb8oxGToX\n5k/pd1wMFCBo+5jWRT0K0U6DRUgV73wjV7wH1++Fj9tSCgxuJorNkSfIfcOs\nm3Q/7C7p8JKlDjTWPv5MyFSJ5LJT/ME8tU67aSTiu/KiuvcleI20yYPbuRWO\njQqgHmT2PcG6p3U2N4VpTete8Ql8b2zVsr0N0Gl9xPIH/nQwUIEvGeVNW2n1\nOABq/N/GCB4tfRiYscHNF+8hX3yq0+/j1XF5E7oR9LPQWoKDA5TrdDfo1RcL\nVSr18WYUIvLnP8gbyubGRUolqMZQgaEvEJe3dcAvvBiy39UxZcHhsjdH5oU9\nRwYCLikQM/yP0sdi2qO36VRiuqyu8mI9L5v+Ad9/ryE51VHaz6L/btczO1g/\n/5hgI0FjeRmxWinQkC/xvdU1kPU4pd685ZT3LUMplR6OLm2fzm+w0K0MI/0a\n0ESNY2/39t/4PA1Y8pNOqwff76usT7QTtM3XIo1i1Nc7M6XI7UtTZDfmkUMH\nmA30agGhOa0x43r+eyWogtk4eyWKIRBXhSyeMKOEKgk+czI/1YdXz8BeCkrI\nvNrw4VGc6S1Mo7D1QI5iTesanGYvkZXVO9ua9wqI+sK0FcMqyAPfEAq1G62+\nzUFnI4SOwzndbfaHnjF5OHZthnylIZH4UZiemNOCf4Gt6CqiPpZLuHFMksEB\nrlzO\r\n=LNgh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDNfIY5ENn85ZajNkNNsNjwJCzvxkKHfRGgwAaOPeekyAIgDXVSQefCHXwP4CTEsxVyY/aviPfyd4FJDA9YwtSVP28="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.23_1605092704672_0.8872970057259262"},"_hasShrinkwrap":false},"3.0.0-beta.24":{"name":"nextein","version":"3.0.0-beta.24","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^10.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy } from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `fetcher` \n\nStatus: **Experimental**\n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths) can be used with this new experimental feature.\n\n**NOTE**: For now, all posts rendered in a dynamic route require to have `page: false`. \n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n#### Caveats\n\n- Post are required to be marked with `page: false`.\n- No fast refresh for post changes.\n- The `nextein` Link won't work since page is set to false.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"65264e7edb485248fcacf71872435e8588f3b4c9","_id":"nextein@3.0.0-beta.24","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-9UBK+v2kznN0N1FU2DAS0xs3ZJi2CNENrm5Jo/ATmxjLs7MiQm1SnIwD9OgWaiI9DGu1jfimV9MSPJz1cLoP3Q==","shasum":"632268ae69228d0ab3ff80bc76046a92c56b4fe3","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.24.tgz","fileCount":48,"unpackedSize":171822,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfq8bqCRA9TVsSAnZWagAAC9wP/2++Hn2TWSV2G2o+y1Ei\nOABuRHJZYlWSIWz3WTrlEWosfTNKOTqigna2ivKGbN1y4E9Ch839cCwUtpaH\nVV6KmOedH4M8fKHZPOTnOiIxHf6RWvEdd1NWdPjB/+R0Tr0rbq4Q2PKPBUD/\ndX99r3TTAXSOz/AjQfK+YcTP64T2GZE2pJxKfP0uomJcxkx8c7bav1vPMbuR\nhJNdKfCuftyt+BMFPLvi8bt2Fya1dXkcvGZIGDlnuwLWAK/riCPd/YCacOwT\niRm6N0R1l6HAtt4UNLUVaTwJsUFnwEN2IGLk4vk/qd+ozIrpf9OtSIvYA3/3\njBYrW6QQbZGvGS4rDijC4LRSjAxR6/zuUdktZEePDJL2+MJsRXdgG1ywLdT7\niUcd/CovbGHuCAFmIWKeznn34h5c3knTE5BsJPm2U46RpWCBBmaz3T7uDu3k\nVz7ysFVm6xl4w8ome8glGaRWFW94ZcUKEFay26edxtZrVlkTj+CFo2p/UsLA\nKbaPHvPosnjmgWzsLxgMVqdy8FHHR4FFmBXjm9jq/DHhiG0IYiRdOOKKzRrv\ne+XzIod9JNqSN7entl2Blj6CPmZH0lybwl8VCF2/Jk+38yk5r9qz45UO7W5y\n/LjE5RbLMqWTk10n7BA1FGmFh1XSE76bf/7wLMftVS238bdY5K/dyn/rEYpO\nwAqM\r\n=p3h/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAvlgwjioAp3teXpBuzqkHyVWzDgyezGKNLzAlbDzdHAAiEAzzqoT0A1dN/Zg6CAGSXxOcfvgykJPHIyaQleegH/nSQ="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.24_1605093098456_0.8983955825880312"},"_hasShrinkwrap":false},"3.0.0-beta.25":{"name":"nextein","version":"3.0.0-beta.25","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^10.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy } from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `fetcher` \n\nStatus: **Experimental**\n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths) can be used with this new experimental feature.\n\n**NOTE**: For now, all posts rendered in a dynamic route require to have `page: false`. \n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n#### Caveats\n\n- Post are required to be marked with `page: false`.\n- No fast refresh for post changes.\n- The `nextein` Link won't work since page is set to false.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"04fee353ba71375db7f1dde38ec814466f8b57b0","_id":"nextein@3.0.0-beta.25","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-tZu+JrmdGV1vvYpBicbC2Fi0rwGJrY3cqVda42SS++TeHg6V7GoWPnlKzm4C4TBMS99Cqw9rYUAvb0nJJL65dw==","shasum":"2c23115ae68aa1f4eab14596591905d8863b8e6e","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.25.tgz","fileCount":48,"unpackedSize":171763,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfq8oMCRA9TVsSAnZWagAAMswP/0ke/4T1HOEIiEX7BnBW\nmNOnWwYgVtOUWt6QI2zl7kDLhKolnBHuiyhQFjj0vJXHmjqLluWssoZ2zM78\n3hUOVQeWuQLSK6wiYjD1QmJ29Cz0L6iugxVJs0nmhfTKBpNg4cZi1TFaO0wr\nvU/P5i8CuQiFdfOBJBLV77N/kC2oJMai5gn3YbjugzNKN2PAfuZx2WAz87+f\nhuaVLPN4c+y/yTNpQdzLQZ1vxoiVk6NRqcOUQHU996sj+YdnesNVxhEnTZX1\nE2AX38geSrjNK2O7ump1BTtXOiMxp+2rQB8ARxsVJVWsMUg3Ktn6Dc5IpUYB\n3mwNXDo185iwzDHl3l7Lk7S1SkSGVRx7tf2kscFyZL/YJvCI5kGiCOMAiK4O\nChgmvXpSN1GQjE3yBsykYeVUpRBVs7DnAn3Zdakbrh2Dcqzbt3QQKN1EvP8M\nc32XIysYa0oKnQXqfwL3OdE9xqcXpoWnYQ9h+cDptIWcwkJjfX5wlPnnWw4C\nFUTIedI/IIPN/PJtVYxVZPTCCCEHoZabYUrvScdPj+zs1hSCae2LZPTWJgIx\nW0sQr7owK9Joad+nRDBnzadqPcxxYtSKgtMxPnLEBLhfIideOB1iuVnWzell\nAFx5dQK3foA20sP5Sc9VNEy/PVETQpgoq/HMSX1Jn2g99ojEoPe9p92E9VOX\nAa64\r\n=K7z8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDyjc/GR9N6ttjDbSJk4BF5y8E8Lu+cInqM0K9Q9n7llgIgBo5A2pc0qEoqFYQA+iDKBALRtCq1tAs6rfPvcsAIrrc="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.25_1605093900382_0.10382293775539075"},"_hasShrinkwrap":false},"3.0.0-beta.26":{"name":"nextein","version":"3.0.0-beta.26","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^10.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy } from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `fetcher` \n\nStatus: **Experimental**\n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths) can be used with this new experimental feature.\n\n**NOTE**: For now, all posts rendered in a dynamic route require to have `page: false`. \n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n#### Caveats\n\n- Post are required to be marked with `page: false`.\n- No fast refresh for post changes.\n- The `nextein` Link won't work since page is set to false.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"016c6f7548cab1b05e42e0e5533e8f5c32579144","_id":"nextein@3.0.0-beta.26","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-M097qhOI95p49OpxA5hewQdjex6H1DhIh3lvgcleQnGV6AHQxmdpF8TxwbhOLMViSei+Jq2Anv0JRd4vl2AF6g==","shasum":"e929f86ee46de7eef50947a1efd8d7fc33777a3f","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.26.tgz","fileCount":48,"unpackedSize":171953,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfq88aCRA9TVsSAnZWagAAzWEP/3Mbryy6WIvWIEf77jaH\nZ735N8TU1Bhhv9ZKreXYDRJW/bgonaGfn/MvLOItIOAEpcuk+sSmRXHbDma5\n/yw9hZZNCwF986aRKZ/TuHZmo/6srBsR6hPnOR1kHuUbMVNxgPjqeV4V6BUY\niLfsVVfzAMEOJ8rEH3ouaRTZbnxnslkRA1er2TvHvtop/NCPT1yHEUSu5oVk\ncLX97hiOh93nWeyfAF1CJoz6P6+WQRgW/ShPlDPRPodTkS8o+DdAfMUG03Oc\ngXwr9hzFvSwBWHrc7JaldFGD/Kqxy2Gl13/mzmp6oEG58UTX/YaksaKMAeXP\nogzP1zrsK7F5aTIZ4yYVzFgNYsu3zyNBcENlWIQKmrmcdABV8qnz5xzKAtVL\nkwQ5WCy6NDq6I+kgTsptk28uM44qMjH+eSLNX8pcuaPnxmmLVIwVM4apBGFv\nOddEHYd7xYmgRwmPNbSrB40uNmJvAms0I6C85fIfaPm2cmQiHrSHLmzlDZjZ\nmmxhXIu/y/xoVOfVK8XZdyir8f5ItY+mAp9qhJECOUihLlSfFyW3aWfKBVwy\naf9kUuetm12UKgPZBmtYcfA10+7PRzt2q0MT/G4+/cbubFjSx6p3xTf9XDlu\n7vfyLoep523XqDT6roFZVNbiCsBqrbyKXryJ/i2GbH5XTC7CgUaKS7LoFdqb\nQhuR\r\n=Omup\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDq4JSbrImzcH5fov1FF+ePWXohpt3B4L1VGuM5wynIdAiEA2v8wo7vqNIfXLiFelfDDEtLoCqa5bt9tEGm1H9C7qgA="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.26_1605095194358_0.3664131506214574"},"_hasShrinkwrap":false},"3.0.0-beta.27":{"name":"nextein","version":"3.0.0-beta.27","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^10.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy } from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `fetcher` \n\nStatus: **Experimental**\n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths) can be used with this new experimental feature.\n\n**NOTE**: For now, all posts rendered in a dynamic route require to have `page: false`. \n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n#### Caveats\n\n- Post are required to be marked with `page: false`.\n- No fast refresh for post changes.\n- The `nextein` Link won't work since page is set to false.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"d51c5707fba542609aa6938370b2b116dee55e94","_id":"nextein@3.0.0-beta.27","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-EvKcZonez8Y/on9/ZFmAKcP4WurjAwThnX3FSE6cfUGpVJMnzPRLNeA8dmsU/zLC8qbZoJRaNnRbV7T0dysNWQ==","shasum":"a29d3cf73de62645c53392190d8b81cace5933e6","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.27.tgz","fileCount":48,"unpackedSize":173826,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfsly/CRA9TVsSAnZWagAAWxMP+wflk94oj6HF+o9K6+Jm\n/hYZynJHpJOf6tqehctzGgDvghxAiQGrpbh5ZXx5xj0m7KV2dYStsuV5Hgiy\n4mAR6SmiB6xDAI3f7ZWtsHCJW5CaUUsvfVhPrW7E/YXbM2WHKzwG2R2YEY44\nR0iXaBDlx6VoCjRzNWEuOE4Wx1In96con1heGETU9SrA3V+YvpLZ1Vfj/+zC\nexHQtins/uLhhT5PiU5erOSAdOYZHFsvi4WQFFe7LOQABkJm1DzmdsinpC+o\n8+KjCeSACxGE4+K/Gn2iwO6YOCfLqLncsLYZ/wUP+pOqiaX7riI9CGKWssGA\nCjfvhy8cK8xejuxKJs7eqBXvs1LsaItKp42qSF0DyeJ36sO1RuJgK2RyB3h2\n4/WqoDYaAcvY8b+n03KD3IDGlN4VpC3zD4ejh2AhoARaOo5WvrxK1jOkECni\nrCUpqMlDDbdbYCiIe4h4213NjkpTZztr9dBQa/FjlG6uNRjBxupHTGrjZ/vq\n3kmvypsFG1drSEnFEtB2/7wTbynb1YYVvAGwaB1bdtmfoMJs8xj8Z6xuo6aQ\nBjLAATHwpcQbL1dlZjdoKQWrKmRW0EygRRo9gu63OW/1a0oORHLYCU/nnubD\njfJerMrzpIzw7S7lWAy5Pz9T8BosIlJGEvxlJrWw/z6dAMbsL1R8zs7T8FCy\nrjvn\r\n=+GDq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICx95GQqe/TUqFJNqUZ9E2vfs2DG4r1Y9NMtrm2CBgGgAiEA2ek1Q0dlNgTHbvRKB8GwVjD8Te02ZLyxQonxAN7eEyY="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.27_1605524670604_0.4170821708681247"},"_hasShrinkwrap":false},"3.0.0-beta.28":{"name":"nextein","version":"3.0.0-beta.28","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^10.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy } from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `fetcher` \n\nStatus: **Experimental**\n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths) can be used with this new experimental feature.\n\n**NOTE**: For now, all posts rendered in a dynamic route require to have `page: false`. \n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n#### Caveats\n\n- Post are required to be marked with `page: false`.\n- No fast refresh for post changes.\n- The `nextein` Link won't work since page is set to false.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"a80951903cd243bc30d00818978e1f1c70801982","_id":"nextein@3.0.0-beta.28","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-bWrPtz1hFFCW6X88BOkgnZDc9Ll11ibmB68cryKEU/FykPnBy/PSz6Ak6l7e+g1VykJzdxNjBZnQ/qD2Pu8LEA==","shasum":"2dd421abce3507764d5cfb395f1523ffb22e5511","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.28.tgz","fileCount":48,"unpackedSize":179473,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJftZHiCRA9TVsSAnZWagAAynMP/1S/xit0NfcyavS89Lkx\nhxYQcUq4a2FYJzAbBbL49tiWxc8AlUnCgBP5mgwlCvY/8EBVU4BpHOEzfk/5\n41V6zEU7hXIoTeTXUoaqPT0lTcf/XMab1e0jrcYprNIzLkjzan/PelkDe/nK\nJcPB3TjwUScgicPXdjxwSYPDoIQmpXp4kBBENcF7nTeIg1Nm1V8x0EI61UVo\n2/XpJ+nb7phR2Qv2llesF48Ff9j2NVd3uP+vw9hnYIfwj6wkEV8cBM+2HZQn\nPQHq82P/l3oaWxKCZtnbwSeSENur0JubCLGiTol84kK1lYKWn8LN+Uju5pTI\ntDJKli0RYvU/Dn8lghkMc27Q/kD1thMlaAqvZO9v6h7cA+oB3Y5LWRtsK/Hg\nckg3VbBaWJolhR0b0Eksr87FmxPrMoB9uy9RNKD7eAG6J47xuoWZXUle2SKx\nib3aDJkm9jlcWQP2Tq+CS3K+U3nsAeOYXJVK2dJVC6+8c6M0XeYkYQM6ixQc\nJWkleUTdwROI4AncXtZlcAH3zB/omsNCBaUM3WTh7W3TSVj7UDZ9sWwFghz3\nVhZ+V1F9oNS7VcCbvxqKA56KUUy++xGEAOKn08XtY65YvMhRillCo3mGIjMi\nxHDJqTMoYS5AhBUMU0kq4OvnmLWzO72EcJQ2nyls7UOkzLZ/UBk5eRRyHKC8\nsGVC\r\n=g94N\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGPr2iEUp3UOtupAcwpyAK7+OJu+wGK5Zepe1RvLKLLAAiAUdXAOxZQkK/geqS2cF+GPcxQYfd+MQv2Cc/ZdpIzNHA=="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.28_1605734881413_0.8689167285282808"},"_hasShrinkwrap":false},"3.0.0-beta.29":{"name":"nextein","version":"3.0.0-beta.29","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^10.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy } from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `components`: `{Object}`. Convenient alias to `renderers`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `fetcher` \n\nStatus: **Experimental**\n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths) can be used with this new experimental feature.\n\n**NOTE**: For now, all posts rendered in a dynamic route require to have `page: false`. \n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n#### Caveats\n\n- Post are required to be marked with `page: false`.\n- No fast refresh for post changes.\n- The `nextein` Link won't work since page is set to false.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"684bc0da44c06aa8d1571284ea17c87773858382","_id":"nextein@3.0.0-beta.29","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-dVDnEcJkuy+dh7bKNcpvpG/Uj3c4whA8mO8jLu3BQHVdpC0Oupd/Dy3KOsr/IoZLmGp+IFdLZU2Mh/TkOeFWGw==","shasum":"dfdeb1ee1229a42abf0dd35cd2ff2a49119bc611","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.29.tgz","fileCount":48,"unpackedSize":179449,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfttxSCRA9TVsSAnZWagAAw94P/i9uxtiQgTuHTzD5rZrC\noEmN+AgRj+9/63FDreqIdUyYhByNTeDnWk0vHBCLMD3YqPm2Omgis/p70XrP\nVDjFbaI1qsX8f7xO8oBXfXI/JB37wXQe+vYaUMlz9kWjtS+ufjL+Gd+mRF6/\nKlHEki2jdWK27KAvu8nn/kADB2PGggb3S8nsIoNJnefNB94Gufpo0S70lzYb\npEy9CUw6TwZERBn3X3xMfOBksngIgvHWEziewroz1s7MejB0WXdXMIXJ9Mpb\n1KhrUWxFVWIcoH++WieNhFNAaW6ezkvUyf+hiz2jZ7JREmhiVYUfYmpmFt9G\nVe6GFobvekOYf8RRdSSo04N0fNTZtbYvzoqRnBlFtl3e1PNVxeaV62bMRv0c\niQYUMX39DsB4KPcuzmZw6T9vSt7TjCw2OIKiWqR3ND9Fz6oAD4mqCkORsg0p\nzyHsQ1Gb2yglzgcs5ALpIeRAGZkNLENa5gNImPll7wE9NdE0xJ8So/Vlf5wz\nG5sbgfJphRBh/0UM6EyK4R9hLWJk3ZzV+PmThjkui7vCoFd3c9D6Z8OKkQuN\nND4Gbq50S3Ik461XfE5oLi9Qe2DASxFpVHSMp44pZZvxWCTyPNkdfWF04TmV\nB8CfSv+n6q/onFdClFhRYdC3pbcOMpHD5hNXEZgJdCDtLLJzFdJZ0NomtLcl\n65A0\r\n=U94H\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHmQlF/vryPFp+I2CPwtvQ8nCVkJMWQwR44+WforCuZyAiEAzFu3Dc/nKbfjCGKOoF3I51VfartYzjgYLhlqbZP2IRE="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.29_1605819474488_0.38461233482056056"},"_hasShrinkwrap":false},"3.0.0-beta.30":{"name":"nextein","version":"3.0.0-beta.30","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^10.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n[![Build Status](https://travis-ci.org/elmasse/nextein.svg?branch=master)](https://travis-ci.org/elmasse/nextein) \n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy } from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `fetcher` \n\nStatus: **Experimental**\n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths) can be used with this new experimental feature.\n\n**NOTE**: For now, all posts rendered in a dynamic route require to have `page: false`. \n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n#### Caveats\n\n- Post are required to be marked with `page: false`.\n- No fast refresh for post changes.\n- The `nextein` Link won't work since page is set to false.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"cb5a44a3f4b6fbfd5770fb8c8261d954590692cf","_id":"nextein@3.0.0-beta.30","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-OVLWtyzTMz37mb3JWY6qhKaXrxhyJkbMfGPrhqcomUk6q5H0TwnV6cPBYT0bH0rAd31RaylR8jdIdo86xMhLFg==","shasum":"4da1dd367b0c1f30fe475601c3e8a1e0c5c175b0","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0-beta.30.tgz","fileCount":48,"unpackedSize":179449,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJft7hhCRA9TVsSAnZWagAATUIP/0JR0HQ3SEtYvFyAm4ml\nBjCJ/9/xKfH970qqAoHt9RsME7FjRLi4gRuxX19YU8XL7QU4cN/hXp3e1FRH\n/7K+QRpufaOhHxgvaF2OjgxQNQxmHQWjOpjC/xo6Nc3TcI6W6FUu89vNEAj+\nyF/r5KkuQ2sL+cEOvtlngD8QP7C1IZERLVbYSgHZanyx0CtQlglHoWIEfX+f\n+c0UNjhq9fn+dC7R4cSF76DI7wCWYK89xsTkyTwCMayE6QeNJViYHC2A6sKW\ntQ9xNRp5QK40rrZSH543o7YUpGIXLYVnAfNagECgZGEafhOYNZuW85UlJxhs\npJfamFtYBaEMPaFiBaZfahGxqOdNeZg+sI6Go0uBaTD8DV861PIg76RQIPuY\nX5gO0vUouFar84fR/5sZDQjqvS/hTRiOYguolf0TQMEWQy4EfGEbUv2Kfr/x\ns+H73x2YAB1Kd2QQUh/IW+DjKsnzySBQKYcBgvvNyDt6tSyGKqG/V0Frjokl\nlAT8F8VY0saw2SGzMwL7/qSAPOKVk9bt20N6PdXYF7fQcZz0OxEV0T20QSPH\npSrTLXyTSBmwjk+7HoRw7XT/pcGLHhuAaWc8gl7766QhH9WMD/Pp8wVryj4z\ncTOPHLEXyKdqdnWn4qFoQkkcekgK4THRGdYgB7ynOSjCZ5GyXxqbNvbNqoe5\nxBju\r\n=x80P\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGUF+m/xY86fjS5cI3Tpq++nvv3YLL3XBamvdbIDq2GlAiEA10OFIi8AFBl0/9wm///Xx/p2ylSLNxtQ02NWaywWrGw="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0-beta.30_1605875809058_0.7158196018585821"},"_hasShrinkwrap":false},"3.0.0":{"name":"nextein","version":"3.0.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^10.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"gitHead":"fef93d8dd83a575664beabbf4f5780565946a613","_id":"nextein@3.0.0","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-kbKXiswkHUDEJqjEvhihNZESwHiIkOe9fi7gNqVjtZOfRxfXUkt6N/pQnd3pXDdKeVJ7ZkQGDVgxEeXtjjRpqQ==","shasum":"8b6188f7465232cdd409710173041eca10e3e753","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.0.tgz","fileCount":48,"unpackedSize":179534,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfuAPeCRA9TVsSAnZWagAAHeAP/AoYZRsOgK57xl/aj7KR\narV/1gd2/1YYfqWq/8uCLuYFyHjDQoLB1a1qvnMsvKoKWfAbxBXPbi69tJ0v\nd3aBq8ImjFdCSfk0NE5bqRzQyUPoJ781i2SVakPxiugmz2sGx9J+4ZEq6vxW\nuP8tGufAW76ng3lYpkXUV8KALB7kbdL8NjdKn/GXjjzxH9JO6gae09b/x18A\nfKJWbHsa8lHPUzGR5jsoAgh7Hrnbu5puVlPzbmLaY5epvKm1iJXbNvPVaI2W\nSH7XjuNqxPfH7hB/kvM348yz29iH4Uz0JMfbdnTyJcj/nu+iE0gPEvmUhVrG\nC018psb7m+9/AfQ7yDXmFpuHQutYMu4ky537XBbNOg2CbQ3jdB6KZLvHPnrf\nqJH9mvF502vs1AaJqINLOc719vJn+j8woyvMnz22D23psPl9oRRUfFYRU3Gb\nE5IedtD4be37ckOPJElDso24dMa7gC/EtfE98U+SPloSgoU29NUJFKp/4eOc\ndNmlCgEAv3Ogcx+7Wed1XeZ5Bme80TQ/JhkqrFSFZgOSS61ziMEBNoDykX4y\nH7xAmoW+Gv3PnpGOgUMUnQLUJuQC/o+HNrGEZa1YrUnFhOGt6hJBQtsB/nQl\nNqi4EaoTHdren/PG3LGikOtjgFcLC3l4xGFylWGsUlUZ2L9kNQFovotATe0m\na3ZO\r\n=ygjz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCffg7AzepaMRZeCAOb5BfJKLPQ0wqMBJH/lPDwQAM18wIhAMeTM0SfAezXRRUTjl9gHJWkmCynnLfRVRc8ZenRxKwR"}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.0_1605895133212_0.49865882795283833"},"_hasShrinkwrap":false},"3.0.1":{"name":"nextein","version":"3.0.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^6.0.0","rehype-raw":"^4.0.1","rehype-react":"^5.0.0","rehype-stringify":"^7.0.0","remark-parse":"8.0.2","remark-rehype":"^6.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^2.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"7.9.0","@babel/plugin-proposal-class-properties":"7.8.3","@babel/plugin-proposal-object-rest-spread":"7.9.0","@babel/plugin-transform-runtime":"7.9.0","@babel/preset-env":"7.9.0","@babel/preset-react":"7.9.1","@babel/runtime":"7.9.0","@geut/chan":"2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^24.8.0","eslint-config-standard":"^14.0.0","hastscript":"^5.1.0","jest":"^24.8.0","next":"^10.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^14.3.1","taskr":"1.1.0","taskr-standard":"^1.2.0"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"gitHead":"b9d8538917a037984f661140942ea32a33bf8998","_id":"nextein@3.0.1","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-EGguc50UT4peRDS1s7oiXPc1TwhfT3itRz0cP1TQztAAHP7OxFJKw/KSCsiCf8UL1ppY2GnOt13Hydx5uAoNrg==","shasum":"84d0542a8e4d946b650ea6de88c0765e0c8fd022","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.1.tgz","fileCount":48,"unpackedSize":179774,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgNUF+CRA9TVsSAnZWagAAO/EQAJzWfD9vSlZJQycdbDaw\n80uOs/IwlSkbFrScChS60VhVOGkRXtNNib5t/G/gx9ApNSsES5PkIwf5DVB3\nhamb77rcYpIxSn5C/1fCYzxRAe6bbTN/n7UKMzXh71quYR+vaFQ+IwRVHSO+\nMaJ5H1LbZ5sG6fy5oocntubWl4UysaVKMTbD9POp8dE+9ee/Rge91vpfHcsv\nbzzTzS8qzpKunY5AGvKrWJNMWOvGh9d6WklDCdPtjBoQhgq7J5jGWiww/gej\nfm1j6HJZL/C/x+yn5if3n9YPj2g3pMpnnoavEM1vwLt04o1a87mRMsKZupzv\nkmqQBaWOXqvy9NsYt9krJjWGx1gnNKBHmV09ZEDW+Jd9djxsqpSTwVwKEHUP\nWatm2ogDknvQU8ZEw4w3JYnexJsg8k6cbBg5xHLfbszc/ccZdAlcpRbxUu4a\nBB9ZVQA1JhpTDi88FsuKGmTA/V/t/e0m+b9s56i2LErxCGOeu0EGZVgn37DW\n7ul/9j30DMRckbyRCfU+ZvbyhSRiRJpEwCOoUdm76LdvZGNE1fhkt3OBGUVD\nv77c4qsZpEQ3XxQ8Y1EhX7+RGoaL8gv7236ctfH8t5CwNgPaIQmlaCg2NO/F\nKaaEFsgf0M9vpZqZg2c3aLIhW1337POa7tywX7rSQ04ZSmoZgBN69l0PYxIV\no8rv\r\n=NH+r\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCaMS/VSr2EQADYDv7KEW3VFPQ2xlPzBdxR1eDu5RCv5gIhAPXDmcaFSb97pqjQIn8rgVJPbi4FxhdjHDTRc7jaFxyr"}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.1_1614102909566_0.49331418392689397"},"_hasShrinkwrap":false},"3.0.2-beta.0":{"name":"nextein","version":"3.0.2-beta.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^7.0.0","rehype-raw":"^5.0.1","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"9.0.0","remark-rehype":"^8.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^10.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.38.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"readme":"# nextein\n\nA static site generator based in Next.js\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/elmasse/nextein/node-ci)\n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy } from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `fetcher` \n\nStatus: **Experimental**\n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths) can be used with this new experimental feature.\n\n**NOTE**: For now, all posts rendered in a dynamic route require to have `page: false`. \n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n#### Caveats\n\n- Post are required to be marked with `page: false`.\n- No fast refresh for post changes.\n- The `nextein` Link won't work since page is set to false.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` ['plugin-name'] `: Just a string to define the plugin.\n- ` ['plugin-name', {  }] `: A string to define the plugin and a plugins options object.\n\nThe plugin name should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts' }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n## Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"15d4c1afbda5e685cd2e6be841ada63c55ec4b2a","_id":"nextein@3.0.2-beta.0","_nodeVersion":"14.17.0","_npmVersion":"6.14.13","dist":{"integrity":"sha512-VHzjwJQs55ok3BbYuqwBvzNvlDba++g1BX5HWF1Oa2qd4+yjOTvNsmMi2XzGLwmC7EQ+V0uI7gw2nOsWEnGXRA==","shasum":"d6c6f3dfc3c761d2b731c8e1fb8d02f75858848a","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.2-beta.0.tgz","fileCount":48,"unpackedSize":188144,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgt7caCRA9TVsSAnZWagAAhnIQAIvLJ6ucxw3UW2cDkKhf\nOYO7PA8mu/f4q9JutT5D20PBI501mocJECSL8Rp9T2rMT+GLLuqbhPXNrlGv\nPeQVOxBamN0P7foXFnC94F/sN86AfYp7xzqRfv8N7YkrTpORQ+OK0kJiG3rA\nNLFcHNq0WtYtUrwszgFLhaQCFOU5xyyNEb0LKCMuYB/MCJQlG23PTL8i70W+\nGQpERoX4g7JKmQ1amX+UEo8V0iGYikIzyF7LhFiFhDMk08hd9lyek5OXcSmf\n05/kZ8x+CpHDotNzkKhr46gGZq7WkXL6E8b7NXAfBlURTBf1QKNz4ItZa24S\n7uqJx/kYO1cjmaFjmTqcYSouEivQCpcGyVhBokrkFuFJaKFdNaul5Wtz5Ril\ncPgGrHikvh608SDW3NDANAeIvVwCunrvtdOvIBcIpYTvJs87zmQ6VTcLRwLH\nkpRQ7gziLFUtoUZu2n7o5V7Eptz22XQiUHu2w9nU7UVy+rksFPEWzY9ydQrE\nvsyhqhLwM2tj++042Bhc8qCXgcI67VxWHKgIikisjXBoICf2TqMa4ItEe88b\nPd5/6vLXPdzAKUAdf8Dt85xQpb5XpTnz+I7vqbapkImmIZtTbPvyIlITc9Gw\nM8aw/MntYBZyVDMtV9eUzzoJdZAyjxCNFxj54lbedyHjZV9uKI/E61u/oXyS\nYiIQ\r\n=aU2n\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDCTAtlfL1UOEYvf4NqpXBF854ivIvyyZAjdBlESCXQYAIgBsLSJgcq+/aampyHwCdp2lCcvfhWAQ7Nq6C07hh9Vgw="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.2-beta.0_1622652698123_0.8331016736682446"},"_hasShrinkwrap":false},"3.0.2":{"name":"nextein","version":"3.0.2","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","postinstall":"opencollective-postinstall || true","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","opencollective-postinstall":"2.0.3","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^7.0.0","rehype-raw":"^5.0.1","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"9.0.0","remark-rehype":"^8.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^2.2.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^10.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.38.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","collective":{"type":"opencollective","url":"https://opencollective.com/nextein"},"gitHead":"d9d28f4a5165a67ae1ae6841b422615879ea1277","_id":"nextein@3.0.2","_nodeVersion":"14.17.0","_npmVersion":"6.14.13","dist":{"integrity":"sha512-5vC3peU9kXNk/gYCYhHjBKcN+m5ZQQ7iqkNdC0oBDQcHIwaqeQK6YvREx2evIxEMNi4HoEhG/jhcrgMDiv+3+g==","shasum":"6630e3a65229a8dedd9d372726c4470b166dd1a9","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.0.2.tgz","fileCount":48,"unpackedSize":188306,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgt7sdCRA9TVsSAnZWagAAcK8P/18sWBrhj0UZQZkCiZR3\n1dnfTDZ+eqRrtpyXgcmoD82MwTf1Zg0xUMKPUiD+4lIKzZHzQoku2mWNBdSR\n2/QV6fTPEpMQQW234dFbNnMMw26aqTYmOGS/1Q89cvm6E1sqOEHT3K8zzkw7\n/LpKJtJGAugdcH5fHs/9sCUTwa2UBoW6z+69g0CsAGGk6HrmHeuUZ8X/Lihv\n17WekPBuqRg/JtYr1RrTNNB2jlwdLIbN3j9OVjXzpAYqRR2x2OwpoufujT1U\nG//TH/iSrf/RGkcjfDlMDkZ8CUF8/tiPx+4ToZu8OY7M2Al0VnToDuo2fMVB\nG7tmo5mDRzrGPrUtQ7vObb9a1NGR6+8O4F/r3TWIbYEv4UWtUjc6BYhFxcDZ\nwrNHE0pwStzZFPNMx6Ps17LaCjeIOpHCcr1mNrKiQ53+0i21DOsiQ6QfdwZC\nh+AOMPsySP/bL2nu/p3tvI2CKR6vidvZsrosj+pW+VULdWJkAeG8Ez1uxhhA\ns2iFiFcuy7My6E0/el+Ov8bCzbzlWDrTsCWscrCTXmA9F0jh3MUbsXY5C+6I\nahiJw/1C7DkWUEIQMqgtwCyGbYlxvtYQ0r0dgfauLD0GrLzq8r+QtHUcjPRs\nSaSXMkg2Uui0uX6sZD8OPOtdesPnW80St0nDigQ+6FkBWMP3xDabnJlVXW7r\nY8sY\r\n=brLt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCW276skcQrkGaIoEzRtLcMRogQaP1OkEEEUo2q2QhPvQIgYB71Kzrx6F2bZEle0wnkj1rfY6KQyrAWFRHfArESRqU="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.0.2_1622653724971_0.06333053424823509"},"_hasShrinkwrap":false},"3.1.0":{"name":"nextein","version":"3.1.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^7.0.0","rehype-raw":"^5.0.1","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"9.0.0","remark-rehype":"^8.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.0.0-beta","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^11.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.38.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"831a5d0f50c18e5f1eac1d728e616cda93b9db84","_id":"nextein@3.1.0","_nodeVersion":"14.17.0","_npmVersion":"6.14.13","dist":{"integrity":"sha512-tjOUvbFENhwstUAbauOuWe+VwE5weEjfrMPNfw8Qm4YJuB1MtRXts/VxEfIIbSsMpTOJ2U6BdAh+TMz6D/yGVw==","shasum":"7af49c1744bacb3eeff82a49d20607a5bd2987c8","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.1.0.tgz","fileCount":48,"unpackedSize":188364,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg00BcCRA9TVsSAnZWagAActUP/ixik8xhNwL9Z+XM7rEB\nNAxkQlOTq0W/m6pp+TyQ3+PNmOD6jiItkInNK+h2GrFzpQEUFdhdV0GAKmcb\nhoUcTszRGFUYmCbnWNCc1JVx3jsj6rcbUkIWkBYWmdNCo7b9+qQ3792wllro\nmzlR1YsscsG8DXaw+FSAci8pm4TGnqGAMEGDnBXu0HGYZUk9yZY7t5ote+OK\nFlHJ7wFfr6Pvcf2dvA48bGvoRx/7wRUWb8MocNGozm03NXGSaZbRbSp0RBK6\nEWvmNNyvqatTYQw/OinNrgGbfVdm2rzzt5SDIxuGj0HIm66nBeLotBcKABNo\nTQhYPWTDkxwlxgZHt434xXLR06mzGaxUkgNDywH3nLSCq5ly08hZZPoNThv9\nrBi4UDhH/BVNfKzzeEkDhFXECcowEBgU1VQe2qF6yXprLrv9Q2FYnfiSS2E5\nBabRYUTI0T2xPAScIn5dVoGnxtMiwmzfQFQra6AdC3Y3nkD1vYfuDgh9mYkl\nkoznxS9eJrwJACx5tYvysqRQTiAlMuQhFajr5YZ5gG7TYMQqKKtSZTyHx3Zm\nKEVKuWOOCzLgo1e25xiL/nzbU84ibyoCFKD+Yv/ZipT4omjIb8uRh/LEVTHM\nv06SdUavcHDD5qa+BtXyVAV15/glL9QAd2XBqOyriqyZmE4PACeo39ZDYQl6\naoXr\r\n=+5pD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBrfj9OrKqsOvrh7cr44cfwocRuP0PV72SnC1xEG+F2OAiEAlOfSUvrIFhDuTRCs8UyYQAHYsrj4K7qdreNVnHdMlGE="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.1.0_1624457307370_0.8140531819805685"},"_hasShrinkwrap":false},"3.1.1":{"name":"nextein","version":"3.1.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^7.0.0","rehype-raw":"^4.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"9.0.0","remark-rehype":"^8.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.0.0-beta","@taskr/babel":"1.1.0-next.2","@taskr/clear":"1.1.0","@taskr/esnext":"1.1.0","@taskr/watch":"1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^11.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.38.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"b44ddd166980af88820c9ee03000cca385a98df1","_id":"nextein@3.1.1","_nodeVersion":"14.17.0","_npmVersion":"6.14.13","dist":{"integrity":"sha512-oxgqi1esfi3N5NgFIkfixeIqkgAOpUVJPc1I8RwnSGln80eyf/JCG8noPz8rzkTuo+4LfHx7ER5RRUzMUy8iUw==","shasum":"e1c7ecbab06cd3f898608d8b7ece37bb7a8a44fc","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.1.1.tgz","fileCount":48,"unpackedSize":188483,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg04IICRA9TVsSAnZWagAAVV8QAJeb2U8z6ZdXx1QWxcbA\nZCmtdtc6e5OyUbHMseoZDciLH/AixinH7LX3y0yXvKrouXvDsNW/e1f5djTC\nINmFOWyclCyt9Fq0Aifh4OOEYtYYfvpGMLlxxm2PRMrhMqUvC9JQoRl1VKMO\nvyg+yt0TJjKmc3aRfQPAST45yIwRNYlrABteoXjT1dLy+RcSL2Fl1LuxFGzH\nZsiudp23xfqz/20iBEMzohScRoaFqeMQOlUrhqvfDmERuP++V1vjO3Nyxf6N\n9OnkhhbqBlca6iwoplXkhP4xt/dE8wUPeKFvzEgq/3zr6HMlmPN32s1MyLGG\nqCDG2jsnrHt1JKlmPx+buxKOtExQ9c+xALTitHR2nPymBqsfoO1uxxr5jWAs\ngslJUwYM7o+e5uNJIs/FbiIfxarg2LgJueId82fU9Md+KtjwYm3AzhdL9sx+\nkXwIHrNPZqbBSoQdVn6IniSREtzSjyIi9vV7nfB/joOmY2tZrsoU9q17ELhm\nstSCqSxMt/1C16lKOEgg0au7gE40J4DHMCl2yw+fgHqL6oxZCdfU3cRGgljD\nu/LlUgK+Z3hKXpySq8vlYE7JESkU55RrXdWPUHHJY/gTH5YW1WFn7ZdEJiOI\n7lx4PItNNtdxewaSaNXpOQLUXf6cg6YPNWolhBuc2CXLYc0DogLfX4jWkzUi\ny4kz\r\n=nsdj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCd7IY8hm9egaF5VZ+WNyAQKa44h42hfyd8VK9XVcN7lwIhAO6UYrDPuMgQIj8Frkceqw8eiIirdf5yK9NgexfUjiuX"}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.1.1_1624474120263_0.6857583892480399"},"_hasShrinkwrap":false},"3.1.2":{"name":"nextein","version":"3.1.2","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","build:watch":"taskr watch","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"^3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^7.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.0.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","@taskr/watch":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^11.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.38.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"c86bd81aedc7be39a05fb93456a9bbd591ac292e","_id":"nextein@3.1.2","_nodeVersion":"14.17.0","_npmVersion":"6.14.13","dist":{"integrity":"sha512-xkUHeJWVb3RBW/0KRzXQ1C3o42PgXwjZ5pzq8cN12uhGAeF9setP04sdiuk5r88u3aYjTQV6lB3vjFV2jLR1yQ==","shasum":"58be6a4af4515a90c23b3284bd43a9a2860bc526","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.1.2.tgz","fileCount":48,"unpackedSize":188818,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg1clzCRA9TVsSAnZWagAAQXEQAITYJ1H2eWDA0bKmmsoA\nKW2HAaKqzsuZCJES1h5D/TbPCkXRbv8G2Ii6MgJdte1KtmqLpRPX/RztWlNv\nyT8EMJluRM2k1nokNWKLVtnA7HEysjEIIE4i+szfPN2RGXPwZNXFao7Y1NLm\nL1oAtXJXWdBEwZaS5k8GaxGXkagB913eQYoBREekDAQZP15uwWHtCX/rH5sf\nNjz6sjzjkiRUHZpD7Vmtw4qsZAtF1Ka2demMqZfkNgv4N5K8lrw0KTpPD8ih\n96ZwiIvb+h2dOJoGZCKh7zofml5PLm6XRVAsuNgiybpy/V5l98upaOE1DnnI\nq+S8oZkuF40VU80nefhL3HEJIhGOMHtM4S5SeqCugAlN3lrRxJQmWUGDA+03\nWJyxMlhiKobmOgXAeqZzto587ZMtqcFo5iEPehXi0wnFVWg9LoNiYyC1Ixi4\n9T48q+1m9jHiQo3LpI8KK5QBk81JgJVLRQjwpXiFTJcTKZfcfcFU6pE7mnoQ\n9bjcV/I2lIm7S0loWG27b12j+BZbsavz0MON2bMbDRki3/LolVhcRtTIW0Hh\nXo82vlHMS3Tds2MOf74Dvh/HCrexITspJUuq24Uf/Op46cy+4evwaTkPWLLj\nDFGgtmBBrbyz7aQ7BwFMoAOw/DrW1X/4afV8emH560rxZQbHhipS6ZNBNcTF\n2isM\r\n=5If0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCBhn8HCCAgZNlQOSVPrd3JE7mGd63stryvOeajoswmpgIgUZVK78AXL7srfgpqfHmjojkVPTIsFnCHJLvAPf7zPB0="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.1.2_1624623474813_0.2363290151539903"},"_hasShrinkwrap":false},"3.1.3":{"name":"nextein","version":"3.1.3","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"^3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^7.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.0.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^11.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.38.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"88d67ec86f34bddded417f5a899e1102ca02a71d","_id":"nextein@3.1.3","_nodeVersion":"14.17.0","_npmVersion":"6.14.13","dist":{"integrity":"sha512-z7WOZEtOIp6QCTWrk33V0Ejumf+vg/tVxg6P2taiUftXxmgU8P3/RNCXjFJWQNDUIVSDRFkHML3Vw0ymUk75bQ==","shasum":"0aac0a91294281fadbf58b0c480dae3b0f1c51ea","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.1.3.tgz","fileCount":48,"unpackedSize":188932,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg+a16CRA9TVsSAnZWagAAhMEP/jUFsgxoCGLlYGTD5UAW\ns5YgYK59sD3psE63LOHLxtXwzwCj/ozFUITxxEhjAoqrV3Ex7e7d9y4o1apH\nwzSFJNi/ev0C7yGQde8E2XWZi+0Kir9omKpkL70kkdArCA5DWIRea5ZqTWB3\np3cnC9sSjZBiQfyIL8JReyYHCa6PK6JHk8YyUJrjVFT/Kt/D+NIj60dnS4GF\nprDGpkZ1n4GhU+NoJPDAUGKWqhtDUmD4YORq0Cag4u1yYTtVxRho6OKATzGu\n3leaIoqOX4vghYnxVMCA82v0Q3fZNkyT9i+SepxaX+cffVFiyqvLNnOzAzbL\nApK/+v0jm/wIGiDNSMWYmkyFyganX3yHy89wZR0Vv2/ryFO7fg1rdAs3pppA\nmkZslY3C/y1TWxVVo6aOMBEowxx6hQ4sMfu2sH7jjtiUNhA5PuKJfMtvGv/C\n/89swfygHDcFYYcZnzBYPhu5xw0jNG2T/uUEe70pVhml38+5wwM4a/O3QUXw\nmpJ+73u+41NkzDEYegu0TzQcgl2GWIIApyjIECb/K3GGfjJOv9mBp3bnKeBZ\n+hvT3P5KsIyQpyaGv2R1ps+V7/lB2NMIfA1tZXMZswxSF0ugR5g8G/uh42W+\nU64VTi0JSUtvf5kVAiw+M0q1oORNNTU3IPjk3qkqZUNUrKHkt+TJL2GCLHQq\n6DMm\r\n=ukK9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCVctjv+HjL/p0xBQmViq80Lg8T82Dqpx75t9udSrrX7gIgEhwhHTosKaedxBFsFwzC5vSZ7JT3teDNdyNF9PCE28Q="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.1.3_1626975609903_0.4951429961131195"},"_hasShrinkwrap":false},"3.2.0":{"name":"nextein","version":"3.2.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"^3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^7.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"3.1.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^11.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.38.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"c4a2c4ccdb1655a741b0320b5c866d8664df9a78","_id":"nextein@3.2.0","_nodeVersion":"14.17.0","_npmVersion":"6.14.13","dist":{"integrity":"sha512-XzCUcM/v//li77s7q+BOpU7ZdkqxnmeutneR3Qq7rjBFj77K9Pyry5LG50zVMqrbAsniHiaE83NoDPHiQUX81Q==","shasum":"234a84dd348db3db8ce7366e7518c514cc21c18e","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.2.0.tgz","fileCount":48,"unpackedSize":191399,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhCWyYCRA9TVsSAnZWagAAUJ4P/jTCPQk2UsDrs26+YsbS\nSvEJj0rgc9CJGs4OQyyOBnOfDRuUfo9HIfGhMPkJajcfDFCtilpPvK/x6Oel\nmMq85TR6eEb9xapprgqx+o5qgiF0k5qRDOQ0yjjjKxJC7spztCaiCVmHbsst\nulRZSwbAKcQ8fLLiZNgPxDXpnr6MXgYpSCTDz5raxlnkbr+i2MT6NO4vvIv5\nP9+Jp7cdSaSOPum08P1hRqL5JIci5BcZykaau2rT46dYAJSv5ETTMC3FFBNS\nNmWn1UTn64//4jUiBehKD6UXWR3uL8vaXKrP+0G8x66b/FNw9XGDLRN/6GpT\nCgj6lcNb4Smch+MeO8Ko/Klz8jVU5riaWSn/QMLY4IJCLX/UaRLCHED6P8Sr\nuaOPsRNLqoDCqpT9Q4XEYuwOS0goq4FEXIVZHXpAHNG2JShYgQ7XvyKrHLaZ\nJ/gL7Ceu7YSTWDIs2qc/0kPtKMgOjuZNBJVryWmiB7GByQQOD0GZmmes6Owj\n0/zujA3fA7/zgOl306FZJQssK7pHc+dTzCbc/NkVPnBahFB4+6Rd544tzQC+\nATFLXnr1lJIwlSTbuIEYt+FWjTeOVS/NMW3/idkASQ/dl5jc0UUP4TUsTOgl\nZcqFt7SZpAqDuYb8CJobCiMGaLCMX1p7OqsLSTGxXoq+Eas0CPYUbUw8jQHo\nzYDP\r\n=TQlq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCybS6GF1irpyunjwgCiAECwqHgQHTzBi+zzpojI1OZNgIgHJYtkOeHIf+sJ+aTCYQwvoh5pAlzVFDFeKh2jkcbV24="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.2.0_1628007576140_0.6039270548020099"},"_hasShrinkwrap":false},"3.2.1":{"name":"nextein","version":"3.2.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"^3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^7.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"3.1.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^11.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.38.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"a5f6e04a29fa9b3feedf7c9b811f56951d7ae4c3","_id":"nextein@3.2.1","_nodeVersion":"14.17.0","_npmVersion":"6.14.13","dist":{"integrity":"sha512-2oFR6FmJUe1PhglwfZKHyiLoi+i4WWtPXTffcPIw68HlJFH54nSrmGvjwLxgOl8Ih67ocfOgHs193MMmeNDxJQ==","shasum":"b178f757b73b97e0d8983a0c6c2cdc872719d2df","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.2.1.tgz","fileCount":48,"unpackedSize":191822,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCG4+XgBe4Au3DeJkr2OoaoHNiSD7KK3PPouO9RXASZ1AIhAKFga0notD4NX7ZyceYHyPQjQZDJRpNhqYOKN5xA5mop"}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.2.1_1632505722668_0.3921461868631557"},"_hasShrinkwrap":false},"3.2.2":{"name":"nextein","version":"3.2.2","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"^3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^7.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"3.1.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^11.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.38.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"f18b3bdab22176d449b45d87a67fd91e164bc4ba","_id":"nextein@3.2.2","_nodeVersion":"14.17.0","_npmVersion":"6.14.13","dist":{"integrity":"sha512-Uin0Edt1JQumBN/7m9QCnGyJfbmLZkLNNtx3EuLTDiV92YixjPv0So+GA79K/VRwZCbAKDJat+rsQMjNoqSCSA==","shasum":"7bf0ceace2e645cab4af4e336015269b4dd64deb","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.2.2.tgz","fileCount":48,"unpackedSize":191970,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDfwmeoQgmwdqHpApjMBLcjrL1ur37pi5NkxD1qIhnKbQIhAOxwEGBPHVDIhWqm3AhvkOt9E9Hut504e8j/0gf2dFI7"}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.2.2_1632509454828_0.292831112641569"},"_hasShrinkwrap":false},"3.2.3":{"name":"nextein","version":"3.2.3","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"^3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-parse":"^7.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"3.1.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^11.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.38.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"670a6a24cc02f36da9f731ad2dc5e4da0c1f711c","_id":"nextein@3.2.3","_nodeVersion":"14.17.0","_npmVersion":"6.14.13","dist":{"integrity":"sha512-eo+3Pn9eGz5SKexgk2Pyl5glWbbvxquiQvUNJ8xEab9Ar4nzxCGXROLuq1a5gODGlO8jEq3GNHmrkH76jndpZg==","shasum":"f27bf388e066d120293c4b87ef783f215d5ef105","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.2.3.tgz","fileCount":48,"unpackedSize":193185,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDp+B/8yzFJTcQEdoi6MthTM4QIjQNc79rAbbdfMBvjmAiATiW8mAk7/9DQSMCNNIYhMLsJWQPxb8iH0ovu8j0WojQ=="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.2.3_1633013435745_0.11101041671921141"},"_hasShrinkwrap":false},"4.0.0-beta.0":{"name":"nextein","version":"4.0.0-beta.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"^3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^11.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.38.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/elmasse/nextein/node-ci)\n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import withPosts from 'nextein/posts'\n    import Content from 'nextein/content'\n\n    export default withPosts( ({ posts }) => {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"nextein\",\n      \"export\": \"nextein build && nextein export\"\n    }\n    ```\n\n## Documentation\n\n### `withPosts`\n\nHOC for `/pages` components that renders a list of posts. It makes the post list available thru the `posts` property.\n\n```js\nimport withPosts from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { /* render your posts here */ } )\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `withPostsFilterBy(filter)`\n\nReturns an HOC that gets all posts filtered out by the given filter function. This can be used in conjunction with `inCategory` to get only the desired posts in a certain category.\n\n ```js\nimport { withPostsFilterBy } from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nconst withCategoryAPosts = withPostsFilterBy(inCategory('categoryA'))\n\nexport default withCategoryAPosts(({ posts }) => { \n  /* render your posts here */ \n})\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `withPost`\n\nHOC for `/pages` components that renders a single post. It makes the post available thru the `post` property.\n\n```js\nimport withPost from 'nextein/post'\n\nexport default withPost( ({ post }) => { /* render your post here */ } )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `Link`\n\nYou can use `nextein/link` with the exact same parameters as `next/link`. This component wraps the `next/link` to simplify creating a _Link_ for a given `post` object. When passing a `post.data.url` to `href` it will generate the underlying `next/link` with the `post` information.\n\n\n- `data`: `{Object}` Post frontmatter object. This is provided by `post.data`\n\n\n```js\nimport withPosts from 'nextein/posts'\nimport Link from 'nextein/link'\n\nexport default withPosts( ({ posts }) => (\n  <section>\n  {\n    posts.map( (post, idx) => {\n      return (\n        <div>\n          <h1>{post.data.title}</h1>\n          <Content key={idx} {...post} excerpt/>\n          <Link {...post}><a>Read More...</a></Link>\n      </div>\n      )\n    })    \n  }\n  </section>\n))\n\n\n```\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `fetcher` \n\nStatus: **Experimental**\n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths) can be used with this new experimental feature.\n\n**NOTE**: For now, all posts rendered in a dynamic route require to have `page: false`. \n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n#### Caveats\n\n- Post are required to be marked with `page: false`.\n- No fast refresh for post changes.\n- The `nextein` Link won't work since page is set to false.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\n## Plugins\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` [name] `: Just a string to define the plugin.\n- ` [name, options] `: A string to define the plugin and a plugins options object.\n- ` { name, id, options } `: A plugin object. The `name` field is required. All previous definitoins are transformed into this format. The `id` is optional, when provided allows multiple instances of the same plugin.\n\nThe plugin `name` should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts', data: { page: 'post' } }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `data`: Default data to be passed as extra for each entry. Default to `{}`\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n### Writing Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"23247d9a27746f5c5751213e079f6c1720b79059","_id":"nextein@4.0.0-beta.0","_nodeVersion":"14.17.0","_npmVersion":"6.14.13","dist":{"integrity":"sha512-b0kmL8hB4HUE2ikyAMySngnMAcfwrZylWec06fjhdzaGTnAgGoxucw81uO64pnXaJPwQpsLw4cuNvL0q1dQEFA==","shasum":"2e1ef83deebd4ed717a88ed9928972af151f9d50","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.0-beta.0.tgz","fileCount":31,"unpackedSize":112419,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID97y1OjIFI+cCqBjnhW2vvbPnphbYLHMGnVCLJVMYJoAiBgWpIjru2xTgyRBtn8JCdwXS+nvVEPe2PuUUCp2uQv1A=="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.0-beta.0_1634311441983_0.9702782622645516"},"_hasShrinkwrap":false},"3.2.4":{"name":"nextein","version":"3.2.4","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"^3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"3.1.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^11.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.38.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"45f022f7f64eb34cca6e3fdef819df5afe5de917","_id":"nextein@3.2.4","_nodeVersion":"14.17.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-Bo8WfQw/dFfpCMUWz2ihJBlCPdn48HAwUNLDM8NFfRZzDpWgQmQ2VjY4IPv91UBzYhT8OxJB9RgkDq+3I9lLuw==","shasum":"c42907c8063b978431d9f7bdeaa96d2b8090be57","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.2.4.tgz","fileCount":47,"unpackedSize":185725,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCJovWrjS7mzeqREZ4iduCYHExP8IpUXbKw0W9KNas6bgIhAMAu77MhBGSSW41mVk95EVPYg7OffcmBGwg6H2ZvS814"}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.2.4_1634562134566_0.2581854146509681"},"_hasShrinkwrap":false},"4.0.0-beta.1":{"name":"nextein","version":"4.0.0-beta.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-match":"^1.2.4","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^11.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/elmasse/nextein/node-ci)\n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import { getPosts } from 'nextein/fetcher'\n    import Content from 'nextein/content'\n\n    export async function getStaticProps () {\n      return {\n        props: {\n          posts: await getPosts()\n        }\n      }\n    }\n\n    export default function Index ({ posts }) {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\",\n      \"export\": \"next build && next export\"\n    }\n    ```\n\n## Documentation\n\n### `fetcher` \n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths).\n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\n## Plugins\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` [name] `: Just a string to define the plugin.\n- ` [name, options] `: A string to define the plugin and a plugins options object.\n- ` { name, id, options } `: A plugin object. The `name` field is required. All previous definitoins are transformed into this format. The `id` is optional, when provided allows multiple instances of the same plugin.\n\nThe plugin `name` should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts', data: { page: 'post' } }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `data`: Default data to be passed as extra for each entry. Default to `{}`\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n### Writing Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"b22503a416a4ab2659e2747488c94bb2a641be99","_id":"nextein@4.0.0-beta.1","_nodeVersion":"14.17.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-mAIcLKECoc1pZ0f7UIE+eWe1sFs7yzaboGHkGJ5b35ZfUVqlXbiMWiImEVnXalbFHvoHw4QrRfRtSr0sIw3aEA==","shasum":"2b3fa42e2c958f99ab9beef587486530dc44cf24","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.0-beta.1.tgz","fileCount":30,"unpackedSize":103054,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH/39mDIxmvOt/eRENW4TbKfY9YZ9e5dIPKWiQxzfulpAiA9in3ur6zR8/vJGFlXJ5rpEaesocTl1ZIGgfCrKBrZsw=="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.0-beta.1_1634590751836_0.8798096934070287"},"_hasShrinkwrap":false},"4.0.0-beta.2":{"name":"nextein","version":"4.0.0-beta.2","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-match":"^1.2.4","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^11.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/elmasse/nextein/node-ci)\n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import { getPosts } from 'nextein/fetcher'\n    import Content from 'nextein/content'\n\n    export async function getStaticProps () {\n      return {\n        props: {\n          posts: await getPosts()\n        }\n      }\n    }\n\n    export default function Index ({ posts }) {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\",\n      \"export\": \"next build && next export\"\n    }\n    ```\n\n## Documentation\n\n### `fetcher` \n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths).\n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\n## Plugins\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` [name] `: Just a string to define the plugin.\n- ` [name, options] `: A string to define the plugin and a plugins options object.\n- ` { name, id, options } `: A plugin object. The `name` field is required. All previous definitoins are transformed into this format. The `id` is optional, when provided allows multiple instances of the same plugin.\n\nThe plugin `name` should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts', data: { page: 'post' } }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `data`: Default data to be passed as extra for each entry. Default to `{}`\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n### Writing Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"05986990ac9a22cbb7fb61b42865c14e945d8f51","_id":"nextein@4.0.0-beta.2","_nodeVersion":"14.17.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-07C3usXj4iLRE05owunQK4NSzELoPNJVBldwutDgQMX4nltD+JEruzcu61lGIY2BZtrSNJwpEBv+WP2fRDZcEA==","shasum":"310306b09474c4fa06ddeac782ae59dd17ff2108","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.0-beta.2.tgz","fileCount":32,"unpackedSize":109139,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD6+LjQYgLeQatlbSDBPGETuGGyWr9vzTCKvNsMhzWwJAIgad9pESMowpvZvbb0idp7ufCwasCeLNQD8RnIVBBCYeM="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.0-beta.2_1634657922056_0.44556316118208983"},"_hasShrinkwrap":false},"4.0.0-beta.3":{"name":"nextein","version":"4.0.0-beta.3","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-match":"^1.2.4","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^11.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/elmasse/nextein/node-ci)\n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import { getPosts } from 'nextein/fetcher'\n    import Content from 'nextein/content'\n\n    export async function getStaticProps () {\n      return {\n        props: {\n          posts: await getPosts()\n        }\n      }\n    }\n\n    export default function Index ({ posts }) {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\",\n      \"export\": \"next build && next export\"\n    }\n    ```\n\n## Documentation\n\n### `fetcher` \n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths).\n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\n## Plugins\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` [name] `: Just a string to define the plugin.\n- ` [name, options] `: A string to define the plugin and a plugins options object.\n- ` { name, id, options } `: A plugin object. The `name` field is required. All previous definitoins are transformed into this format. The `id` is optional, when provided allows multiple instances of the same plugin.\n\nThe plugin `name` should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts', data: { page: 'post' } }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `data`: Default data to be passed as extra for each entry. Default to `{}`\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n### Writing Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"c0f0970c53510b53347f0df463de1029f9be79bc","_id":"nextein@4.0.0-beta.3","_nodeVersion":"14.17.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-odaa1KFMr3Igp9RrceIxRwFf02UsMSnlHFh4Qk4LuP3Gxt/+p+aVcKsGDGRuYcpPDxIyVCPRAcSfz+qZq9o3nA==","shasum":"f96f8e14d72d57991169c9a24c4c91aadb852d3a","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.0-beta.3.tgz","fileCount":28,"unpackedSize":93332,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCVyDjhIFboteY2+aotEg0GeIDRwBj9nA6OJnQ2iwQvNAIhANv7FcZj12aXsmThLg8sKAT+fYeKOG4nafghsQC3YcOE"}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.0-beta.3_1634734428517_0.9658689839556649"},"_hasShrinkwrap":false},"4.0.0-beta.4":{"name":"nextein","version":"4.0.0-beta.4","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-match":"^1.2.4","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^11.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/elmasse/nextein/node-ci)\n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import { getPosts } from 'nextein/fetcher'\n    import Content from 'nextein/content'\n\n    export async function getStaticProps () {\n      return {\n        props: {\n          posts: await getPosts()\n        }\n      }\n    }\n\n    export default function Index ({ posts }) {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\",\n      \"export\": \"next build && next export\"\n    }\n    ```\n\n## Documentation\n\n### `fetcher` \n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths).\n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\n## Plugins\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` [name] `: Just a string to define the plugin.\n- ` [name, options] `: A string to define the plugin and a plugins options object.\n- ` { name, id, options } `: A plugin object. The `name` field is required. All previous definitoins are transformed into this format. The `id` is optional, when provided allows multiple instances of the same plugin.\n\nThe plugin `name` should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts', data: { page: 'post' } }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `data`: Default data to be passed as extra for each entry. Default to `{}`\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n### Writing Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"45e7379e770c0d229dd98137c4ae12dd41f6da69","_id":"nextein@4.0.0-beta.4","_nodeVersion":"14.17.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-fvSQOWMAv/Y+WFcGg6vVfy14ST2NJ7Vl9CvkStAY4++cCKIiGv/0rENMMfc1mybjdhYAq1pn8fYzmKyfdTHySw==","shasum":"8b45c9c57155e1fd7f901e0d2c296961768777bd","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.0-beta.4.tgz","fileCount":28,"unpackedSize":93334,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC6buIegzsq7l9dabuPEQyM5Yds+ZvYE41OQZJoiPlZCQIhAOWWCGgDh91YwZ2IHH/Lrw7HXrC6Z9n8SMfGIZEzZ06h"}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.0-beta.4_1634745149216_0.4867103523682794"},"_hasShrinkwrap":false},"4.0.0-beta.5":{"name":"nextein","version":"4.0.0-beta.5","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^11.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/elmasse/nextein/node-ci)\n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import { getPosts } from 'nextein/fetcher'\n    import Content from 'nextein/content'\n\n    export async function getStaticProps () {\n      return {\n        props: {\n          posts: await getPosts()\n        }\n      }\n    }\n\n    export default function Index ({ posts }) {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\",\n      \"export\": \"next build && next export\"\n    }\n    ```\n\n## Documentation\n\n### `fetcher` \n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths).\n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\n## Plugins\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` [name] `: Just a string to define the plugin.\n- ` [name, options] `: A string to define the plugin and a plugins options object.\n- ` { name, id, options } `: A plugin object. The `name` field is required. All previous definitoins are transformed into this format. The `id` is optional, when provided allows multiple instances of the same plugin.\n\nThe plugin `name` should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts', data: { page: 'post' } }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `data`: Default data to be passed as extra for each entry. Default to `{}`\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n### Writing Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"d17c236fb5162960fb4ad8d3bce7b27c3e6c24a9","_id":"nextein@4.0.0-beta.5","_nodeVersion":"14.17.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-2amd6Y4RJYRAj86jaVg/bZ3fdOkTEtR2DBNzS52A+Y3nbIgW0IQI5IOkKSQMMbk1FxaAQH4iMH8tBTh/1nPzTw==","shasum":"3e2ce61a28d90b945aec3698088759894b70fa04","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.0-beta.5.tgz","fileCount":28,"unpackedSize":93216,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCKlpCOe4CJMpI4PybyuPpg2ezBk2R4GRTRvlIq3UuEeAIhAJX1HQzWeGtH68sw+Gq8nDwW901oA6tw2Y0R7dgpUgSO"}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.0-beta.5_1635767895272_0.06801175577325758"},"_hasShrinkwrap":false},"4.0.0-beta.6":{"name":"nextein","version":"4.0.0-beta.6","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":">=11.0.0","react":"^>=17.0.0","react-dom":">=17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^12.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"5a4feb691b4ca51b29340402d5d2c2f231ca6c19","readme":"# nextein\n\nA static site generator based in Next.js\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/elmasse/nextein/node-ci)\n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import { getPosts } from 'nextein/fetcher'\n    import Content from 'nextein/content'\n\n    export async function getStaticProps () {\n      return {\n        props: {\n          posts: await getPosts()\n        }\n      }\n    }\n\n    export default function Index ({ posts }) {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\",\n      \"export\": \"next build && next export\"\n    }\n    ```\n\n## Documentation\n\n### `fetcher` \n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths).\n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\n## Plugins\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` [name] `: Just a string to define the plugin.\n- ` [name, options] `: A string to define the plugin and a plugins options object.\n- ` { name, id, options } `: A plugin object. The `name` field is required. All previous definitoins are transformed into this format. The `id` is optional, when provided allows multiple instances of the same plugin.\n\nThe plugin `name` should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts', data: { page: 'post' } }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `data`: Default data to be passed as extra for each entry. Default to `{}`\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n### Writing Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","_id":"nextein@4.0.0-beta.6","_nodeVersion":"14.17.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-CTsf/caEYVKA0w11q6syxcUdHFUcUtFzMbtXiPoJLd6QbqidgWYpXFlJsq/gaaC7MPixBpVhm82/pvbCZYldNA==","shasum":"5ad55496f50488a64a30ca418e31e1753cf9ed4d","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.0-beta.6.tgz","fileCount":28,"unpackedSize":93177,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBF4uhkuJjmLktu5/Fu4nwNNXBCcdJWoS3zg9waQKywjAiEAzQgWgzRFWOEIdcj28BgKYrzvr3OKRXhXz2ux5mIAFfA="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.0-beta.6_1635770434368_0.7566162104833203"},"_hasShrinkwrap":false},"4.0.0-beta.7":{"name":"nextein","version":"4.0.0-beta.7","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^11.0.0 || ^12.0.0","react":"^17.0.2 || ^18.0.0","react-dom":"^17.0.2 || ^18.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^12.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/elmasse/nextein/node-ci)\n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import { getPosts } from 'nextein/fetcher'\n    import Content from 'nextein/content'\n\n    export async function getStaticProps () {\n      return {\n        props: {\n          posts: await getPosts()\n        }\n      }\n    }\n\n    export default function Index ({ posts }) {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\",\n      \"export\": \"next build && next export\"\n    }\n    ```\n\n## Documentation\n\n### `fetcher` \n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths).\n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\n## Plugins\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` [name] `: Just a string to define the plugin.\n- ` [name, options] `: A string to define the plugin and a plugins options object.\n- ` { name, id, options } `: A plugin object. The `name` field is required. All previous definitoins are transformed into this format. The `id` is optional, when provided allows multiple instances of the same plugin.\n\nThe plugin `name` should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts', data: { page: 'post' } }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `data`: Default data to be passed as extra for each entry. Default to `{}`\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n### Writing Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"aab74a6314da514b9ab90f194019e27f28eeb8c0","_id":"nextein@4.0.0-beta.7","_nodeVersion":"14.17.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-HbWi4d3e2l1+A9fLyVmfrGO836xWcq8oLmAnuJYisx5mRV02B4P7HDg51z2NlhzYJa39NzlWoXNpxGg60NBGQA==","shasum":"dbf789fd80dafb4ba6c192b012d6dffd5f3b5e72","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.0-beta.7.tgz","fileCount":28,"unpackedSize":93206,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAZZEps1CROmsiYO/mRe5ZQ1gO8+Zv+1xXQydN9CgOocAiEA2wqRbsHaFM65tbYGRkztFWam5yAftV9uzqWKwyn3HyE="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.0-beta.7_1635770709986_0.11070572760068265"},"_hasShrinkwrap":false},"4.0.0-beta.8":{"name":"nextein","version":"4.0.0-beta.8","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^11.0.0 || ^12.0.0","react":"^17.0.2 || ^18.0.0","react-dom":"^17.0.2 || ^18.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^12.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/elmasse/nextein/node-ci)\n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import { getPosts } from 'nextein/fetcher'\n    import Content from 'nextein/content'\n\n    export async function getStaticProps () {\n      return {\n        props: {\n          posts: await getPosts()\n        }\n      }\n    }\n\n    export default function Index ({ posts }) {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\",\n      \"export\": \"next build && next export\"\n    }\n    ```\n\n## Documentation\n\n### `fetcher` \n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths).\n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\n## Plugins\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` [name] `: Just a string to define the plugin.\n- ` [name, options] `: A string to define the plugin and a plugins options object.\n- ` { name, id, options } `: A plugin object. The `name` field is required. All previous definitoins are transformed into this format. The `id` is optional, when provided allows multiple instances of the same plugin.\n\nThe plugin `name` should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts', data: { page: 'post' } }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `data`: Default data to be passed as extra for each entry. Default to `{}`\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n### Writing Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"688406097eb45096ccc11c1dfbcfffdeee83924d","_id":"nextein@4.0.0-beta.8","_nodeVersion":"14.17.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-sIksG0OOetCzav+hawdc/wqKKRAw8tp6kzLCHUn/CKAiQYQxj9TyRa3vQlY+n1nI5n/BOVWKHZ8SAeMrsfjgTw==","shasum":"82b8d605da065c581c8fd785e01fe48390419ee3","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.0-beta.8.tgz","fileCount":30,"unpackedSize":94621,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD99ih0YlOnCY8GMHfN5Ka0FZZCwRysQMS0UwNtpaxkSgIhAPIJxnavUqCJf11BtlwCWPUOmeKkA+rZuYDuW60EqAu7"}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.0-beta.8_1635781182949_0.5746900569609104"},"_hasShrinkwrap":false},"4.0.0-beta.9":{"name":"nextein","version":"4.0.0-beta.9","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^11.0.0 || ^12.0.0","react":"^17.0.2 || ^18.0.0","react-dom":"^17.0.2 || ^18.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^12.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","readme":"# nextein\n\nA static site generator based in Next.js\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/elmasse/nextein/node-ci)\n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import { getPosts } from 'nextein/fetcher'\n    import Content from 'nextein/content'\n\n    export async function getStaticProps () {\n      return {\n        props: {\n          posts: await getPosts()\n        }\n      }\n    }\n\n    export default function Index ({ posts }) {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\",\n      \"export\": \"next build && next export\"\n    }\n    ```\n\n## Documentation\n\n### `fetcher` \n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths).\n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\n## Plugins\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` [name] `: Just a string to define the plugin.\n- ` [name, options] `: A string to define the plugin and a plugins options object.\n- ` { name, id, options } `: A plugin object. The `name` field is required. All previous definitoins are transformed into this format. The `id` is optional, when provided allows multiple instances of the same plugin.\n\nThe plugin `name` should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts', data: { page: 'post' } }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `data`: Default data to be passed as extra for each entry. Default to `{}`\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n### Writing Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"b3be0e2a4e10367dde4d1b25e61232e6d2d376fb","_id":"nextein@4.0.0-beta.9","_nodeVersion":"14.17.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-sg54J5thcWSmsfgW/FMqN5BDXJOPRmp0Xw2TXQaqv9vdqsiaCEjfElsra887FjHpGXpP9y6iDS1ozsrCrjXupw==","shasum":"27eadab6e73e9d9962c4af520b001286dac40fc2","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.0-beta.9.tgz","fileCount":30,"unpackedSize":97831,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCyBzttBc9HIVN8fJKLkKOYMNl/335cdSNYN3ah5nicqQIgFbQdqXn1GQw+ukVCSERQXwhTEHOap2GCpBsZe3fXwpQ="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.0-beta.9_1635955041267_0.09192540223544676"},"_hasShrinkwrap":false},"4.0.0-beta.10":{"name":"nextein","version":"4.0.0-beta.10","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^11.0.0 || ^12.0.0","react":"^17.0.2 || ^18.0.0","react-dom":"^17.0.2 || ^18.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^12.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","browserslist":"> 2%, not dead","readme":"# nextein\n\nA static site generator based in Next.js\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/elmasse/nextein/node-ci)\n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import { getPosts } from 'nextein/fetcher'\n    import Content from 'nextein/content'\n\n    export async function getStaticProps () {\n      return {\n        props: {\n          posts: await getPosts()\n        }\n      }\n    }\n\n    export default function Index ({ posts }) {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\",\n      \"export\": \"next build && next export\"\n    }\n    ```\n\n## Documentation\n\n### `fetcher` \n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths).\n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\n## Plugins\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` [name] `: Just a string to define the plugin.\n- ` [name, options] `: A string to define the plugin and a plugins options object.\n- ` { name, id, options } `: A plugin object. The `name` field is required. All previous definitoins are transformed into this format. The `id` is optional, when provided allows multiple instances of the same plugin.\n\nThe plugin `name` should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts', data: { page: 'post' } }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `data`: Default data to be passed as extra for each entry. Default to `{}`\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n### Writing Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"c5cc9703893af24d99845164b87b1609c77b1531","_id":"nextein@4.0.0-beta.10","_nodeVersion":"14.17.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-TagQFbAeVTPmGHgZj1Y3ZoLJD53r1F0HDFqFemHdu2OsnaG9MXHodnRfHDlPGVfLN60Bud7WNTSkeNFc9ZVQaw==","shasum":"66f43e2b4d7f76b34b0248c30213c013d8e834e2","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.0-beta.10.tgz","fileCount":52,"unpackedSize":104148,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEhkhRw/dEKvZPYCjp5NK9xowGqN7sYiBoaWm4/lFBUEAiAN3y7dIQ+cXRFxWn688AnC5YDsUM5oSc/uBa0UQdmUfA=="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.0-beta.10_1636039559184_0.23758367554624082"},"_hasShrinkwrap":false},"3.2.5":{"name":"nextein","version":"3.2.5","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","main":"index.js","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"bin":{"nextein":"dist/bin/nextein"},"dependencies":{"chokidar":"^3.4.2","cross-spawn":"^7.0.0","frontmatter":"^0.0.3","hoist-non-react-statics":"^3.3.2","mime":"^2.4.6","minimist":"^1.2.0","object.assign":"^4.0.4","path-match":"^1.2.4","path-to-regexp":"^6.0.0","pkg-up":"^3.0.0","react-display-name":"^0.2.4","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unfetch":"^4.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0 || ^12.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"3.1.0","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^11.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.38.1"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","gitHead":"f5391cc909a55f784094edad4d225ee4ef7c0b6b","_id":"nextein@3.2.5","_nodeVersion":"14.17.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-nahKsecrkOIlmdgJdm6QfI3koQRoN9Gi1p7zwjKX35hwqxziASfwoFAtCOzpP261VsY0D5HJrQ2l7v8VSXIN3w==","shasum":"7896927d0fe991d08a50812b48241c395d2bf8ad","tarball":"https://registry.npmjs.org/nextein/-/nextein-3.2.5.tgz","fileCount":47,"unpackedSize":185736,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB3WHbRcK0IT5BuDIoaErghumzsRy5BzDpBHk3BxHH7uAiEAhIOcx0eHijdWCtHg9C3dKmr/D1S8I5si0+llv26TatA="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_3.2.5_1636041803147_0.09826682060428427"},"_hasShrinkwrap":false},"4.0.0-beta.11":{"name":"nextein","version":"4.0.0-beta.11","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^11.0.0 || ^12.0.0","react":"^17.0.2 || ^18.0.0","react-dom":"^17.0.2 || ^18.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^12.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","browserslist":"> 2%, not dead","readme":"# nextein\n\nA static site generator based in Next.js\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/elmasse/nextein/node-ci)\n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import { getPosts } from 'nextein/fetcher'\n    import Content from 'nextein/content'\n\n    export async function getStaticProps () {\n      return {\n        props: {\n          posts: await getPosts()\n        }\n      }\n    }\n\n    export default function Index ({ posts }) {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\",\n      \"export\": \"next build && next export\"\n    }\n    ```\n\n## Documentation\n\n### `fetcher` \n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths).\n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\n## Plugins\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` [name] `: Just a string to define the plugin.\n- ` [name, options] `: A string to define the plugin and a plugins options object.\n- ` { name, id, options } `: A plugin object. The `name` field is required. All previous definitoins are transformed into this format. The `id` is optional, when provided allows multiple instances of the same plugin.\n\nThe plugin `name` should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts', data: { page: 'post' } }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `data`: Default data to be passed as extra for each entry. Default to `{}`\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n### Writing Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"77212991445529c9f4cc8a6d4ac13ae27e279ae3","_id":"nextein@4.0.0-beta.11","_nodeVersion":"14.17.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-CjZnSC3VxGyT+DIafRFIrk5GaA3XC8i9IpGC0kuTWLzRhO/tsMSFnVTxmr8eAgiRbL1RcSnGD0KkCX4sQ+JLtw==","shasum":"d594325da458d0f3f4dffc6527d4777e4cb706e0","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.0-beta.11.tgz","fileCount":52,"unpackedSize":104667,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDJoQux8JC014GV0E3OussIiae28BlD2tSk1iehxAH0rQIgDa7RrTQI132SHL89cNQn3q7d7vDF6TtcMypaz/tkEs0="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.0-beta.11_1636125511550_0.3381960434774829"},"_hasShrinkwrap":false},"4.0.0-beta.12":{"name":"nextein","version":"4.0.0-beta.12","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0 || ^12.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^12.0.0","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.0","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","browserslist":"> 2%, not dead","readme":"# nextein\n\nA static site generator based in Next.js\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/elmasse/nextein/node-ci)\n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n[![ProductHunt](https://img.shields.io/badge/producthunt-vote-orange.svg)](https://www.producthunt.com/posts/nextein) \n[![Gitter](https://badges.gitter.im/elmasse/nextein.svg)](https://gitter.im/nextein/Lobby)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import { getPosts } from 'nextein/fetcher'\n    import Content from 'nextein/content'\n\n    export async function getStaticProps () {\n      return {\n        props: {\n          posts: await getPosts()\n        }\n      }\n    }\n\n    export default function Index ({ posts }) {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\",\n      \"export\": \"next build && next export\"\n    }\n    ```\n\n## Documentation\n\n### `fetcher` \n\nDynamic Routes and *static generator functions* (getStaticProps and getStaticPaths).\n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  /* render your homePosts here */ \n} )\n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport withPosts from 'nextein/posts'\nimport { inCategory } from 'nextein/filters'\n\nexport default withPosts( ({ posts }) => { \n  const categoryAPosts = posts\n    .filter(inCategory('categoryA', { includeSubCategories: true }))\n  /* render your categoryAPostsmePosts here */ \n} )\n\n```\n\n### `sortByDate`\n\nSort function to be applied to posts to sort by date (newest on top). This requires that the post contains a `date` in `frontmatter` or in the file name (ala jekyll)\n\n```js\nimport withPosts, { sortByDate } from 'nextein/posts'\n\nexport default withPosts( ({ posts }) => { \n  posts.sort(sortByDate)\n  /* render your posts here */ \n} )\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nexport default withPost( ({ post }) => { return (<Content {...post} />) } )\n\n```\n\nUsing the `excerpt` property\n\n```js\nimport withPosts, { inCategory } from 'nextein/posts'\nimport Content from 'nextein/content'\n\nexport default withPosts(({ posts }) => { \n  const homePosts = posts.filter(inCategory('home'))\n  return (\n    <section>\n    {\n      homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )\n    }\n    </section>\n  )\n})\n\n```\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\nimport withPost from 'nextein/post'\nimport Content from 'nextein/content'\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\nexport default withPost(({ post }) => { \n  return (\n    <Content {...post} \n      renderers={{\n        p: Paragraph \n      }}\n    />\n  ) \n})\n\n```\n\n\n### `post`\n\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.url` is the generated url for the post\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\npage: my-awesome-post\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `page`: the component under `/pages` that will be used to render the post (default to `post` which reads `/pages/post` component) **Note:** If you have an entry that should not be rendered by its own page (such as a part of an index file only) use `page: false` to avoid generating the url and exporting entry.\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `permalink`: Set the url using any parameter in the frontmatter object. Default value `/:category?/:name`. The `?` means the parameter will be optional.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n- `url`: **Read Only** The post url.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\n## Plugins\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` [name] `: Just a string to define the plugin.\n- ` [name, options] `: A string to define the plugin and a plugins options object.\n- ` { name, id, options } `: A plugin object. The `name` field is required. All previous definitoins are transformed into this format. The `id` is optional, when provided allows multiple instances of the same plugin.\n\nThe plugin `name` should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts', data: { page: 'post' } }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `data`: Default data to be passed as extra for each entry. Default to `{}`\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n### Writing Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n<a href=\"https://github.com/elmasse/nextein/graphs/contributors\"><img src=\"https://opencollective.com/nextein/contributors.svg?width=890&button=false\" /></a>\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n#### Individuals\n\n<a href=\"https://opencollective.com/nextein\"><img src=\"https://opencollective.com/nextein/individuals.svg?width=890\"></a>\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/nextein/contribute)]\n\n<a href=\"https://opencollective.com/nextein/organization/0/website\"><img src=\"https://opencollective.com/nextein/organization/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/1/website\"><img src=\"https://opencollective.com/nextein/organization/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/2/website\"><img src=\"https://opencollective.com/nextein/organization/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/3/website\"><img src=\"https://opencollective.com/nextein/organization/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/4/website\"><img src=\"https://opencollective.com/nextein/organization/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/5/website\"><img src=\"https://opencollective.com/nextein/organization/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/6/website\"><img src=\"https://opencollective.com/nextein/organization/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/7/website\"><img src=\"https://opencollective.com/nextein/organization/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/8/website\"><img src=\"https://opencollective.com/nextein/organization/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/nextein/organization/9/website\"><img src=\"https://opencollective.com/nextein/organization/9/avatar.svg\"></a>\n","readmeFilename":"README.md","gitHead":"5b798568d176ef7d6a4b13a358d50159ceeed6fb","_id":"nextein@4.0.0-beta.12","_nodeVersion":"14.17.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-3+FxM5O5wqxDdp55p/6HsGoQMJH9gG0ZKMZ+j/eVVukCQZoW0wZIycEWzqnyxgvtURNm8erIDzlrbc9icdoRNA==","shasum":"b3f9be38255d532370dc8f18efd071507ef1a412","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.0-beta.12.tgz","fileCount":58,"unpackedSize":108350,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC6cVH2EtO1iyIMOEKFkxXoZG6Ef2PiojuBbNLnFFHSNAIhAOgBllWdhIjbi49LL4BWg/V4wCEl/5xPbWR7frjc/+ss"}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.0-beta.12_1636133235433_0.5637520801119522"},"_hasShrinkwrap":false},"4.0.0":{"name":"nextein","version":"4.0.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0 || ^12.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint":"^7.12.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^12.0.5","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.4","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","browserslist":"> 2%, not dead","gitHead":"1e6ef24bb6699594317607afa406ce4f0017dc94","_id":"nextein@4.0.0","_nodeVersion":"14.17.0","_npmVersion":"8.3.0","dist":{"integrity":"sha512-u9IoMiEjbqy9II1wvB0sd75i547cr73BrdHntldNOnD/LZXvZBFkA3RENOCShbWWUfO+N6DFBEVOXIJa9XQ2jA==","shasum":"ef37a658ca4d10ad78459ee61ef212aba035a2a0","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.0.tgz","fileCount":58,"unpackedSize":108965,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh0xCUCRA9TVsSAnZWagAAkqgP/iTDcvez/s/wftbVCDRy\nQLM9UMmXIuTDpIiUfXHxlH3xmpqOMfmuRP/qJdc4PQbhYqSwwXyYyfnvForY\n5tS7UbYASDIZ4tp+6L3nCvFDL431Cr8PjordwlGYD3LGs+2T3l9PtUzcFCwp\nweExmkqXBzx7YgYoIpbsOBwCUChsHPuwamDVBjQKPTtsX5dTHH3iuF3spQ3J\ndJZqlFImmE+sr8leTc/SpkvEiiyjT1Pf2e64VzZsLK7KCHlt7aOLtxC3Oo6E\nuQ2r0HKQgqTmSRuxByume/tkRfNfqZg4MEmNti9dTSTgeweHsuWB8vp/Th4D\nTroBtv3C2PP6uT6NGRJ39sjTQIeErX0xxye/0Et69ROHSeN3z3/bjrUz+j9C\nCnKVSYhrDFDObSBWaKM4uY4PjFBWW2BKPjZ043bxLdpR8GoAEMtUoCUYOgC9\nTCZWGYukoOUpGT4JWV2ncvIHtnxd0t0JApsEOoeGmjPg5GwekfOld2ZLGQFD\nUeC4aPofU0rbUSPUEQrBSKc6O6iKb+9xjY7OXWUdHxPTK5JWO1kzZbxPfRzL\nCnH7czhs3gS5UkA1Mf06fuGRA8873m4fHIMpdVXpdfJ95OpvQDJEdNAoPpTZ\n8MWwQ2FiUHdLEE0bo+ThHd4F8eGvDdq08su0jdOHJ90g17z6HIi8WrpGQ9Tv\nd7CA\r\n=yn0F\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDWjq9xi875ndAUeXCK2koalpBQckf6suDlXpEwsd02KQIgTF8zdJ+3FfR/2n2ig9qq6lMjgOQ+KvyG5mCugCGQVAQ="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.0_1641222292527_0.8872751042776101"},"_hasShrinkwrap":false},"4.0.1":{"name":"nextein","version":"4.0.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0 || ^12.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint":"^7.12.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^12.0.5","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.4","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","browserslist":"> 2%, not dead","gitHead":"c26d6cd0c5a48f965a5fb3f6eb167c3f46aeb630","_id":"nextein@4.0.1","_nodeVersion":"14.17.0","_npmVersion":"8.3.0","dist":{"integrity":"sha512-rkKGI5ppw0XeI448wRI0ZCtQkT4Vpk4tLNOXUvdy8IBehVds0eRQqnOEFh/wjif3NYYjPrNqR3YWyEWsdATJSQ==","shasum":"c22675f391e1a8ac8cded51f48e49eee63507d54","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.1.tgz","fileCount":60,"unpackedSize":114028,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh1YNPCRA9TVsSAnZWagAArogP/2rms0x17r0x42MkiU4P\nlquLZ4Cc2aH6UkBSHauKRbGmo/r6OxMc2BsUL01M71xNrRuTN7Fak13abscr\neDe4mQEm4XgKQm6Znyw75J5enP+w5HF4eMEYjlJuLW7KU6THQTVEM054Xegi\nJYdR8Zxa62+PKNBFXVRZorwbMH16trme/qtONlhoPhln2bIniWHPEOh5KWf3\nsIWd7VgFa68nHHNE2ihR29R9xXJMIMyn7/DfAnACeY4PHkJxHwP3PJRwyCEj\nBZ3WoB9GMnnTn6boU9E34fqMzh1qInPWj5h6ZaqMXi8AVqkFkvz4ItdGwyX6\nAh8NyuHQxy+M9aBZI1QhYW2fQiYYD7jsehibWAVDMow4IbkMP7UbT7XchVOd\nQVh9oulw7941gus+L2bOJNIZqhOiSVbIkrS0WO493vL2e6mKM8xIPykqtjZS\nT9CAa5VA36+lxFHxBTUUYC06CngDxRL95oazbq8kpUrUjLihY8MJh0C3Kt17\nhNv4ThULZ3nXjxGd+kowR0Q96mVzn0224XRZcfdBbeAi9s8OMAmlqSavSNk7\nLXkW/4IhMJfE2bvdrEUX5x7/7Eqa5t0GE4kTPj1so4+QmTj+FZVevs5o5GcM\nvtlEibjww8V26A3eZW3OKNPJ364KedDdfXS/S8LsPs6ktCUiatv/JpbSIO7D\n4NNa\r\n=JkyV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEPclGbux59xKo4GTGHNbroOS2kUyqhcaSugRe37CPI8AiEA+mJ5CYpU7V+JUjbf2q7ivrcjvFOhAqJxsrMKYmXxxuY="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.1_1641382735708_0.786392038100898"},"_hasShrinkwrap":false},"4.0.2":{"name":"nextein","version":"4.0.2","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0 || ^12.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.1","@babel/runtime":"^7.9.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint":"^7.12.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","loader-utils":"^3.2.0","next":"^12.0.9","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.4","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","browserslist":"> 2%, not dead","gitHead":"6604c4c608e10ca34261b1fae37344976cb20525","_id":"nextein@4.0.2","_nodeVersion":"14.17.0","_npmVersion":"8.3.0","dist":{"integrity":"sha512-mv1gBxPztrf/Ld2iN7aeGsUxzef5hrPKnjeJ7nZjZp5zjhiSYg/V1LXnXLoLpdpuiAQy95ugWbWUjRRdylcmqg==","shasum":"b3694888d8d1add20b48d55963987ad0bd894c66","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.2.tgz","fileCount":60,"unpackedSize":113211,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh98j3CRA9TVsSAnZWagAAYZcQAINU0Im87uIDXfits7bb\nfWN8bqjSFUGeZa0NyA2LGlTVhsLPCCVASLw0c9zeYQT6yen0OET+IyqM3y8k\nGDDwWbh0D6cWq1XFXA1HTkOYURctxT50ZPOkTsVDXejqb0NWHX0eFwniDjhu\ncgV9qpK+V2yyE2+kXcUIlN0yCcgzskA5BCibgVpE2xuzPCDP27bS1akGfx22\nv0kF2kjMoOHZONce1uEg1k3g6QOBg/7Gi/QUG7grNS8wfHgiDYLigzEyGW9A\nJ9gIkGMPtJu36nmdfW7mM4Zyjk7lmf3tRbapZuTpIKb728p8R/Q3rwnUpt5A\n5oDP/lxWT6c11Q8OsF0HA3zLOBVwPHkJkGRf4Q0D3fPGPTLxb+91ZHGjJSDO\nVlRlebDP8BHHYTvYJ3oMDSBtkhx129M017DE0k5BpUSQxpzGlIz1bwXrC6RC\ncmcZmTJ/pgxkjUTzpSADgNGQ4gIpGzA6ottAXkMsT9COIayEfwSe6DGXUqzT\nI8y8ixVXk1AJaSkNJF0ywirNRSJYSmdITN5f3qezrZvHz7VouLZOVbq5czKc\neahN5v7OI9+v9ShywL8AQ+b5ioPo/paQ8Jo/aAn14OuMMnpjP4N2iuI64jsP\n4MiERIg91igIYLxjZMM8qcZydInnnOc1fPTqNmtaTydQcusYvXMPpeqr/alY\nymB1\r\n=BICe\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDiWhLcGQuldqaoD0aLI/TUQkWw+TeKliw+uBa2IbboVQIgfVv8umk2QDHy54xEfQ0tPcOJUxRELOTwVfX5PMb1yiA="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.2_1643628790687_0.8291305430259841"},"_hasShrinkwrap":false},"4.0.3":{"name":"nextein","version":"4.0.3","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"@babel/runtime":"7.16.7","chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0 || ^12.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.16.0","@babel/plugin-proposal-class-properties":"^7.16.0","@babel/plugin-proposal-object-rest-spread":"^7.16.0","@babel/plugin-transform-runtime":"^7.16.0","@babel/preset-env":"^7.16.0","@babel/preset-react":"^7.16.1","@babel/runtime":"^7.16.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint":"^7.12.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^12.0.9","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.4","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","browserslist":"> 2%, not dead","gitHead":"dc12d748e00c370ea8ab8cc5496e224e9639f985","_id":"nextein@4.0.3","_nodeVersion":"14.17.0","_npmVersion":"8.3.0","dist":{"integrity":"sha512-YbUPy6vdEsakKo3iqkcQPlBz+bCwU1NT3TCh6AFo7GBQac40ag6NFjwujbpi69UIiJpqisX6qxB8QE+1iewIYw==","shasum":"551db61bbd339ed84d8a9e540713455ad132fcad","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.3.tgz","fileCount":60,"unpackedSize":114222,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh9/VbCRA9TVsSAnZWagAAOdAP/1B0qplcRTxbU89ZNKwB\nbYpBdm7K+vVpZJkrlByS0cESymEOLn+AThYba+Ehi4r7BOYyvv7RRVY0PVG2\nZAPyKG/jhe5jmx7HywIhy96nl9YWxxmLDcaP+TlY+urGFp4UdmDU1rnXPowp\nRdpW+rv2z1cUMg/PABtO1fX259hTzuFy0T9jvArHmQEvDeV04gQPjSRAhteX\nM7MNIYl1MAe3D2pbVwjRfMON4486sna1EypkfZSw/jT2uN9faCuLihZdJZcJ\nofsa3jniA6HXFjXkjBGt+nDdQYFw12ZqZhBfM/F1c/d8yU/2MRe4VzVvr3qG\nBLCtuoMytj3t04PeN1+OMeHOfe1Ps4LAbm4ASPUvBVJjqevGkOssG4qjIYng\nR1AOhLgrrVFTW4EURCL8KUljfyxTZmxppKCFVRVF50x7vDksgtZLWAT3Eqhl\nxUjIi5zS5tG5ZiwH137kxulMKuqXdu+l6FJhHfme7IeJgu8jUxkmEqciSWto\nYXDnU8ZBHUAk1YXGm5yEAXXapiHSWvhnobq0NqTold/nKqtW0fKVvVU3+vKz\nbLZI0mkU9VR63hBvq8hpDU628xOP56J3R6FFNhgbORr94t8VNuQvDJogXUcD\nAwI4lkxJgPGpj7Sy6wOKeCQFGvUWu1JZ6UYCj8GHWhvp/vLHaWHMCK/C/oQB\nTane\r\n=rnPO\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCN/FJnUNxRAMEwl2y4fTiw65ZXDJ4rhZtvz6x1QYzfnwIgN8gETYSomvZAvrL03QkGfiUyJhinuNaLkSwp2WZNie4="}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.3_1643640155855_0.3904153262646277"},"_hasShrinkwrap":false},"4.0.4":{"name":"nextein","version":"4.0.4","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"@babel/runtime":"7.16.7","chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0 || ^12.0.0","react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0"},"devDependencies":{"@babel/core":"^7.16.0","@babel/plugin-proposal-class-properties":"^7.16.0","@babel/plugin-proposal-object-rest-spread":"^7.16.0","@babel/plugin-transform-runtime":"^7.16.0","@babel/preset-env":"^7.16.0","@babel/preset-react":"^7.16.1","@babel/runtime":"^7.16.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint":"^7.12.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^12.0.9","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.4","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","browserslist":"> 2%, not dead","gitHead":"96ca87b383ac7c4d46db922db160a5cabdd46211","_id":"nextein@4.0.4","_nodeVersion":"14.17.0","_npmVersion":"8.3.0","dist":{"integrity":"sha512-GikSPFW3l8X4AU1r2f0oOF96t6Njeg1LEClADL59S8OmQ+cAdIZGI4AC7e+U3mUYv+6Tf5OsMFIdTlszGzX0VQ==","shasum":"b38a794c034e483dfabe138f0eba18138435fc36","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.4.tgz","fileCount":60,"unpackedSize":114228,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJiCDiACRA9TVsSAnZWagAAy4YP/1+3EzlklNYCMs+1V6QV\nN1BMclen++wVjTeXMYNlXRqGpV2UwFGWHeIQVvhUdtsLRyuRvmOthAPGUDae\n5+uQysmhBU8DQy+vpX5wF2WCT1qEODpXk+VLgJQK+/bZ7+50NGpmyL7rRDce\nbxaANDtt9wakxyA6T98FwpM2fyQUW2h5zrwDtUMzPJrQgGYEJwVHZICnbVTP\nIP6SYx/jslgwiz8yAQQZwt35ZXAtIX2cHMqJ28LB7qut2lkY0BMxsBW3tLjx\nugC4PyfyAZu7gmEUcVaHNjOdQcJDLecuN2lr0CMdhSRQPxmd6kZKQVeEf8Gp\n9nBzgYQBOLUWGTp4vDdHF364aMQCL4n3fUIzuF2jDB6S69l7xDe/lJX6k7PK\nC2Ja5PVLgcoppKS80/Yzqkx0HWz7HjNhdgu5N/WnPvfKAbmoPIdK7Lh3il0M\nZHzVhK+o0Of7FCD2/vZRw0hm4r8zrldtMUe0Yoqe+OO7JPlUJLMxivtolMYt\njVNRU53yq5m4q3KfVHpQz6+ejHZIyuD9OYRbs7iARVEYJe6ByF26xbSPC7+K\n15jvbYNmqP5lx6fQ0XfrbU/kvCg//T3qSY4G4KsI4CBdk4kg4iiL/HlQH+Yf\n1b6hgT+w9By54ntbtCFRKXkPvp8KB9l//auUIa+TAN0JUPs8MPeV9gTCofy/\n0rWq\r\n=fj/5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDab0orPb0uEzVu/15c6cZMgsnyaVjvFRjOXQ1CwUHWFwIhAMhySUTFPyNZu5aELke/c9M28gQEEY4QOX1liJEdz49x"}]},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.4_1644705919886_0.24426551921704753"},"_hasShrinkwrap":false},"4.0.5":{"name":"nextein","version":"4.0.5","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"build":"taskr build","lint":"taskr lint","prepublishOnly":"npm run release","release":"taskr release","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"@babel/runtime":"7.16.7","chokidar":"^3.4.2","frontmatter":"^0.0.3","mime":"^2.4.6","path-to-regexp":"^6.0.0","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0 || ^12.0.0","react":"^16.8.0 || ^17.0.0 || ^18.0.0","react-dom":"^16.8.0 || ^17.0.0 || ^18.0.0"},"devDependencies":{"@babel/core":"^7.16.0","@babel/plugin-proposal-class-properties":"^7.16.0","@babel/plugin-proposal-object-rest-spread":"^7.16.0","@babel/plugin-transform-runtime":"^7.16.0","@babel/preset-env":"^7.16.0","@babel/preset-react":"^7.16.1","@babel/runtime":"^7.16.0","@geut/chan":"^3.2.2","@taskr/babel":"1.1.0-next.2","@taskr/clear":"^1.1.0","@taskr/esnext":"^1.1.0","babel-eslint":"^10.0.1","babel-jest":"^27.0.0","eslint":"^7.12.0","eslint-config-standard":"^16.0.0","hastscript":"^7.0.0","jest":"^27.0.0","next":"^12.0.9","react":"^17.0.0","react-dom":"^17.0.0","react-test-renderer":"^17.0.0","standard":"^16.0.0","taskr":"1.1.0","taskr-standard":"^1.2.4","webpack":"^5.58.2"},"standard":{"parser":"babel-eslint","ignore":["**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","browserslist":"> 2%, not dead","gitHead":"22a07e255406f0617342c27c7748a95fe760dedd","_id":"nextein@4.0.5","_nodeVersion":"14.17.0","_npmVersion":"8.3.0","dist":{"integrity":"sha512-hDqQVOKRbyg8MC0UGnd67g2A39mwJIGZMiItLLORqfxG7HzqUEMDl9tzYglpA1DZ2f5Fnr+f7TOf3awOG2cgXA==","shasum":"4d80015b550925c31503ec0bd368ea254d2d99ff","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.0.5.tgz","fileCount":60,"unpackedSize":114250,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCU0r+E5tSbdQUnj1Ox4pGVsUdPvQfe5AP8V1gQhfXhswIgTQdu8DiQSxKo+t+sC7zjHph536AgE2LgdzbabP0Ur8U="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiR28tACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrVfg//dIZY4pH5X7ydj/Dyv/nngbs/nzpV7eNlva/ceORMDILznIeT\r\nl1L/uGitl6bLQs2Zjo//vxaHaRh91OZTTxuVp7h8pfE1GT7hr+HjANMz+qxw\r\nIcP3pDYz7S17/x7zLFs+ftpjBJ+Gmk7b/ATy8vjTVZET7fs8enSHOIZw54VD\r\nXKmZkht2kBAo24ueeDZGd6Gknzs1/zSaC3sGaXwR6ML2xBtjuq+Od5xmqXhX\r\nSp/1AqL96NpOfx8xYZ4PSqANFStRCr7y5EOVBYoFiMXSp+Na6gX0pmObFE6h\r\nczoNJqpFFeb/TTSNCFvQumO7O6c9UPglQNbhNviw/tKDYAL34RrDrRrMzpi1\r\nieoiLNsKYoTVPqsx/pdYfgVEJ5+1DY/2pOjkjcOLsMMHoP8JpLKYywHFy7Yu\r\ndHbrxtT3xMGP2W5wknanSVfu9a0OzbG4tGDOEdt2ykFGBBFcK0x/4UkgtiTL\r\ney5jLyck2ozcg9WTl/D80aFK8ahRiiFO3y87ChkO9bhLGDnkqK3vcbe16TSE\r\niVeoaBvdhm1njJg0K4KpTrxTidcsvxofv5UW9+cA/YxyJKEI22GO/daVrPEd\r\nyf3RJU402fRFRiH3+5l5LUlMJu+sZnYniAOm4SRNve3wut5JSl+3plkIcHYy\r\nArdFLweHN3terBYrPlwJogrYfJeUYuVckgI=\r\n=HkC5\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.0.5_1648848685443_0.43592577938166666"},"_hasShrinkwrap":false},"4.1.0":{"name":"nextein","version":"4.1.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"clean":"rimraf -rf ./dist","compile":"babel ./src -d dist","build":"npm run lint & npm run compile","lint":"standard","prepublishOnly":"npm run release","release":"npm run clean && npm run build","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"@babel/runtime":"7.18.9","chokidar":"^3.5.3","frontmatter":"^0.0.3","mime":"^3.0.0","path-to-regexp":"^6.2.1","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0 || ^12.0.0","react":"^16.8.0 || ^17.0.0 || ^18.0.0","react-dom":"^16.8.0 || ^17.0.0 || ^18.0.0"},"devDependencies":{"@babel/cli":"7.18.10","@babel/core":"^7.18.0","@babel/eslint-parser":"7.18.9","@babel/plugin-proposal-class-properties":"^7.18.0","@babel/plugin-proposal-object-rest-spread":"^7.18.0","@babel/plugin-transform-runtime":"^7.18.0","@babel/preset-env":"^7.18.0","@babel/preset-react":"^7.18.0","@babel/runtime":"^7.18.0","@geut/chan":"^3.2.9","babel-jest":"^28.1.0","eslint":"^8.21.0","eslint-config-standard":"^17.0.0","hastscript":"^7.0.0","jest":"^28.1.0","next":"^12.2.0","react":"^18.2.0","react-dom":"^18.2.0","react-test-renderer":"^18.2.0","rimraf":"3.0.2","standard":"^17.0.0","webpack":"^5.74.0"},"standard":{"parser":"@babel/eslint-parser","ignore":["test/**","**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","browserslist":"> 2%, not dead","gitHead":"7ce069a139236c439a3a6031eb98113eee824d90","_id":"nextein@4.1.0","_nodeVersion":"18.4.0","_npmVersion":"8.12.1","dist":{"integrity":"sha512-MSpiBYZKsN6ah4gxx3+31TnMu3YfZiyrAVWXJcU0d4h9O0BvQEmGpwFYbmgvOhFEbdUI7bJv/KnLRk8GyKfFjQ==","shasum":"8e2ebfc8cfbf43983af72dca6b2d14725567417e","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.1.0.tgz","fileCount":35,"unpackedSize":55664,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHu6g1uxvW33VUUfDd69s5PPFGeUImH7ddUH5F6iZAglAiBzelB0V+wfP6duLeYvrk7aFurUwL9kKTc4pgORmDFYYA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi9AtqACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpniw/+KbXBc38SROR8KSdGFduslj4EFucRYLNkl0KsRm2HRuF2C2cu\r\nZaOP6ooiDqDYz41TAIPrjmdK9MZ02QwXS9AwVT/0l/pq0GXpNW8FJFGQ2GR3\r\nYEjaUJiM8K4i/zHxnQnc5Zgr/KyTYWdeWAOOgm+eyVuF5QoMQl1b4zXTr5No\r\nA1qdsQ3iLvhViR5rEWPTDRks5/QXkGs/T1eUap603VhyfEk9JW6IIRc9Z2Ow\r\nFlLe7RJhYRN/TrEEt9zfxVJpvGLZNcuKeB4QyVS4x4fNPEXUA4Hb6N7704Dy\r\nvnaq4Bcig00BF5JcKGVsMc6vnokFo7sQITRcyzKh5pZk+efcODTz8c66aWs6\r\n3wEu6Nj48MBinNNl/Pcf85tTBcVEr/XSMIO0DKDTMCqEivZIg3JkWS5iZZGM\r\nYS1pnYAN44sn8vi8r+M5ihqekQPxj7fGOb/K2KoGJYBGMpFWg4rFgF1WEs4L\r\nh1kkm7BSdA0J7lFgzUb06dPSZRoQ2yqF6ga5Wyn7jZP5m/ebVFShDy1OzGcv\r\nzdi0w1M8dkwJ8dvVbfkhsQO/9TeZPj0skM5BdACWXoz0bVncsGAGfFZ3IYPC\r\nPcrDXpJ+hJXtDl0RfUpbrzs3/bHfzSThkbBUtoyXHLS2uIoy0fFriSheqb7z\r\nzqOzAUcf7hOLfGcO4Y/ugBszdj8NoaDL/Qg=\r\n=TxzB\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.1.0_1660160874396_0.12738750549580913"},"_hasShrinkwrap":false},"4.1.1":{"name":"nextein","version":"4.1.1","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"clean":"rimraf -rf ./dist","compile":"babel ./src -d dist","build":"npm run lint & npm run compile","lint":"standard","prepublishOnly":"npm run release","release":"npm run clean && npm run build","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"@babel/runtime":"7.18.9","chokidar":"^3.5.3","frontmatter":"^0.0.3","mime":"^3.0.0","path-to-regexp":"^6.2.1","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0 || ^12.0.0","react":"^16.8.0 || ^17.0.0 || ^18.0.0","react-dom":"^16.8.0 || ^17.0.0 || ^18.0.0"},"devDependencies":{"@babel/cli":"7.18.10","@babel/core":"^7.18.0","@babel/eslint-parser":"7.18.9","@babel/plugin-proposal-class-properties":"^7.18.0","@babel/plugin-proposal-object-rest-spread":"^7.18.0","@babel/plugin-transform-runtime":"^7.18.0","@babel/preset-env":"^7.18.0","@babel/preset-react":"^7.18.0","@babel/runtime":"^7.18.0","@geut/chan":"^3.2.9","babel-jest":"^28.1.0","eslint":"^8.21.0","eslint-config-standard":"^17.0.0","hastscript":"^7.0.0","jest":"^28.1.0","next":"^12.2.0","react":"^18.2.0","react-dom":"^18.2.0","react-test-renderer":"^18.2.0","rimraf":"3.0.2","standard":"^17.0.0","webpack":"^5.74.0"},"standard":{"parser":"@babel/eslint-parser","ignore":["test/**","**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","browserslist":"> 2%, not dead","gitHead":"7113e944a5b8c2d251e70e13cb33f8071f40470c","_id":"nextein@4.1.1","_nodeVersion":"16.15.1","_npmVersion":"8.11.0","dist":{"integrity":"sha512-TEaF9voHmLHi3ryIiCFyhX2ZNqO6Y1qYypbvrFFHI3bQXg6UXVD3UH+jtzFWua+4IGff8IOxCNWv2GtJK3OXOw==","shasum":"913777a0d41296755c2ecaffb64d4efde5e6e00d","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.1.1.tgz","fileCount":35,"unpackedSize":55993,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBqhe70O8s0WmXdQt4TDWU1mOba8y7UlJrvm8t4T+a0gAiAzxJBuLVjVQkH3gRmIWmUht4T3udljZBTcYo+CL4/nsw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi9BtDACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoxSA/+N0B0H+rv/GGT+1RFxLAsktqEjanLXnHnd0gRYjuZK3f0PyIx\r\nwQOci3P2llU6clWpLPSmRMVXBnuQDODoUGW47IceAPTX79bgjkBZ74+grvGG\r\noSYPC3nUFcDExxTgsxpVGZtHaP9Vv1fYFzm9zMlEmhtALdOyJ2ftHYjLgo8f\r\ncG/P8TX540WN+0zJbANravJa1LN2PnXOl8t6Qjdx2FVp7AQMKb61K1XH5Gfp\r\nTh1ptP9fOAtBFtRCBSqrR1XujorLo9YqzXR7UtQzufqhnjJluFBkq2OuEU81\r\nwO3hwr0kz3RBCfevXbfrp0njbXRZI5KSSjoh6/73UD3xasMd3BBoesPcjdQd\r\nu1vGYIP+mTysvZuwzOvYUTrBijKgiAhXU+H1J/iYrAZ4bYPPmT2xHMqFp/Xi\r\nqMscRSDCKPJ7ifWPCqyi2vZ1dbDfLN1OjvA+mA3wLB6sQ5xoVOC9VZGUP1NK\r\nexI5NlyyU56yB2nHKGE5rupKXK9yBEtH1iOcYI99YKr1udHGedLcrgMIm4yO\r\n2UmYVd8lzRTjZ/omLHbvch0+TA4MihT8lWQ7p7bTBw0RTRS1OeTNZuqOwiRt\r\nYJsFVyULkUSr14kZz5k90sfbssEQGeBYF0+esJtd2ZcmnLP14qfFbumSAQJ5\r\nswe4CmzFDm/rad/OX4KakQY21A/lmKgp63s=\r\n=4ryX\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.1.1_1660164930627_0.8358633328718386"},"_hasShrinkwrap":false},"4.2.0":{"name":"nextein","version":"4.2.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"clean":"rimraf -rf ./dist","compile":"babel ./src -d dist","build":"npm run lint & npm run compile","lint":"standard","prepublishOnly":"npm run release","release":"npm run clean && npm run build","test":"jest","version":"chan release ${npm_package_version} && git add ."},"dependencies":{"@babel/runtime":"7.18.9","chokidar":"^3.5.3","frontmatter":"^0.0.3","mime":"^3.0.0","path-to-regexp":"^6.2.1","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^9.5.0 || ^10.0.0 || ^11.0.0 || ^12.0.0","react":"^16.8.0 || ^17.0.0 || ^18.0.0","react-dom":"^16.8.0 || ^17.0.0 || ^18.0.0"},"devDependencies":{"@babel/cli":"7.18.10","@babel/core":"^7.18.0","@babel/eslint-parser":"7.18.9","@babel/plugin-proposal-class-properties":"^7.18.0","@babel/plugin-proposal-object-rest-spread":"^7.18.0","@babel/plugin-transform-runtime":"^7.18.0","@babel/preset-env":"^7.18.0","@babel/preset-react":"^7.18.0","@babel/runtime":"^7.18.0","@geut/chan":"^3.2.9","babel-jest":"^28.1.0","eslint":"^8.21.0","eslint-config-standard":"^17.0.0","hastscript":"^7.0.0","jest":"^28.1.0","next":"^12.2.0","react":"^18.2.0","react-dom":"^18.2.0","react-test-renderer":"^18.2.0","rimraf":"3.0.2","standard":"^17.0.0","webpack":"^5.74.0"},"standard":{"parser":"@babel/eslint-parser","ignore":["test/**","**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","browserslist":"> 2%, not dead","gitHead":"9fca61988aefdd7950f6cf6f5600b1073f9648de","_id":"nextein@4.2.0","_nodeVersion":"18.4.0","_npmVersion":"8.12.1","dist":{"integrity":"sha512-IJ4ZOLDwg4u09iqTQCX2wH0x70plFjng32BWyPFbkQT7hrPWT2lU2BH83HJOzghXmAwcJoHljMJI9JEuf5CYQQ==","shasum":"eaf9fc1ea240137b9dc5307faede1594473bd868","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.2.0.tgz","fileCount":35,"unpackedSize":56458,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD1YYFtp7TkRgSNY6XXvznxa1yunhSE7mye8TwRmpAVuAIgGUYn92L3kujdL5SMJDWTd3bjo4Ie46d8P6zKJMbPdg0="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjH0oyACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmphKA//c7Aq93RXVu57wpd5zJCCTAuYcscNBZqgtV9uxcHVBbtHtQhe\r\nFRHkMLitMthEft9M8WET+tDXVJOF4IQjDhBB2m76jpDDqWlB8rgTumekU6UZ\r\ng5g/lsxLKolpx+qF7z7TjIL6B534PQWCGA5yDdXJbQ5Ufc74e8wH2XX/tIBH\r\nQH/Ej7EEAAsoMR6pvAREQ+MZx5Zrnb37n7qXu0hKDoYJfOBnZ6EIlDcviaXV\r\n73OYZYARQ3+QqxFuALQL1zQANZ8BsLvK+Ql3sgdmJZN6uFv4uCdk+0gjzXqp\r\n1eLGcbydYONgdPPWai7QoVbf++Baf8kRRWNIAmkGFHhE+3OKX63Eib4VTCS7\r\nBunD9DJLpwKCalqL6mfm6eij0h4NXrP0yJL06bqkdqDepR8psn73Tb+dsrz2\r\nGDegLDujSyJ8mBf0c7QKd5w8ODNyFfg1bhcUuCrAS9J7gVuVtgqzN9rKPqHP\r\nm8gbuUbXvWaF46ABkzOaFq+y5pN0zVe9tksErpTosn0hgk+16K3irmnscA6U\r\nTMtLKfByssvJoQEim6wW2G1n+tZA7+PjDbDrMlkVZn8jjU9jk4nlnUS+GSLU\r\n4Irrq2F2m+7VOBFfgU9zenizbP6uW0m3lQfPk52y8bkiJ/71A/hXa6Bz/jPm\r\nzcGUgothFw/Oyiu+S4RI4s5gAcRxTMkEyus=\r\n=vw+p\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.2.0_1662994994367_0.7852181165240133"},"_hasShrinkwrap":false},"4.3.0":{"name":"nextein","version":"4.3.0","description":"A static site and blog generator based on Next.js","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"homepage":"https://nextein.elmasse.io","scripts":{"clean":"rimraf -rf ./dist","compile":"babel ./src -d dist","build":"npm run lint & npm run compile","lint":"standard","prepublishOnly":"npm run release","release":"npm run clean && npm run build","test":"jest","__version":"chan release ${npm_package_version} && git add ."},"dependencies":{"@babel/runtime":"^7.20.1","chokidar":"^3.5.3","frontmatter":"^0.0.3","mime":"^3.0.0","path-to-regexp":"^6.2.1","rehype-raw":"^5.0.0","rehype-react":"^6.0.0","rehype-stringify":"^8.0.0","remark-parse":"^9.0.0","remark-rehype":"^8.0.0","unified":"^9.0.0","unist-util-remove-position":"^3.0.0","unist-util-select":"^3.0.0"},"peerDependencies":{"next":"^11.0.0 || ^12.0.0 || ^13.0.0","react":"^16.8.0 || ^17.0.0 || ^18.0.0","react-dom":"^16.8.0 || ^17.0.0 || ^18.0.0"},"devDependencies":{"@babel/cli":"7.19.3","@babel/core":"^7.20.2","@babel/eslint-parser":"^7.19.1","@babel/plugin-proposal-class-properties":"^7.18.0","@babel/plugin-proposal-object-rest-spread":"^7.20.0","@babel/plugin-transform-runtime":"^7.19.0","@babel/preset-env":"^7.20.0","@babel/preset-react":"^7.18.0","@babel/runtime":"^7.20.0","@geut/chan":"^3.2.9","babel-jest":"^29.3.0","eslint":"^8.27.0","eslint-config-standard":"^17.0.0","hastscript":"^7.1.0","jest":"^29.3.0","next":"^13.0.0","react":"^18.2.0","react-dom":"^18.2.0","react-test-renderer":"^18.2.0","rimraf":"^3.0.2","standard":"^17.0.0","webpack":"^5.75.0"},"standard":{"parser":"@babel/eslint-parser","ignore":["test/**","**/node_modules/**"]},"jest":{"testEnvironment":"node","roots":["test/"],"testRegex":"(/^test/.*|\\.(test|spec))\\.(js)$"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"license":"ISC","browserslist":"> 2%, not dead","gitHead":"e7ad6ffa0a1258d633afc5fd82a3c69af0ddc081","_id":"nextein@4.3.0","_nodeVersion":"16.15.1","_npmVersion":"8.11.0","dist":{"integrity":"sha512-kkipqNbgie4XxHvA+G6wKkrai5zuG29Wsjqe1Bre6tZ1Au/u2m3qMldZQ1kurud6MbXXW1kz9gN2/SAZKUCklQ==","shasum":"50336698d5cd9c379b38436bda39bd223874aeb2","tarball":"https://registry.npmjs.org/nextein/-/nextein-4.3.0.tgz","fileCount":60,"unpackedSize":116393,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDxoaqDozzrz3Ammj7J3A77q3/lm9ZnahaO8DY/UOW+uAIhAIght/15h8aNZ7ay7j7omTXjsk5Zb93dgTBbnAPe7YMz"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjdS+qACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmppaw//Z4Y8cnalc6lPpXYUHy5TQ2MYCsh3TN/BJ35ji/WVJRUZBj3+\r\nP2Ew2z6D4ygD1eiPo2qez6VdtMeGbK7/RtK4sM9RrL3oDcxZDgrbxP2MFM/g\r\nwDqlBGZHO4f4PkjUNv10Eq/O+Kc9Ra49P1ZZR53ZXWiD7iw5OhqPe5xfPWEG\r\n5Rl04ledGsXdE2a0NUKABXU2Bk93to6RwplYNBIVQ+w7Qv/bb/6FKhyS2qxv\r\n0/kY3FlMmd5ktG05ZR7qdXSxgZ0uRODxGqxa44tgdD5eBny9aQFD1wp6R3WG\r\n+IuCF0AblzNhjTplO0lm4iOAycdygSVBqPkxQxS5hXm7BmTShRD//k1nJOHY\r\nvSngVWwwFQY6Y7pzyTQGkfKaKlUTwgnb5TU1sQBKkqAmGu76JV28HrBw+2vO\r\neNa3pgeEWCP6+fqRYmwTF/yWOFWmfJp217KFmlbtBymwUkoVPpYLHbuQg2oJ\r\n2ol86Qm2prOmhu+6ZBL03OVBY8eQHs6pc64Mtf9FFmUWI4lQI8qagRmzhjhd\r\nQjU0PsUBXR0t0Mq4aEnLBxFLX7OD/K5AOMZfWvUymDEXr844vtbQNfhj3ha3\r\ngjAfwi/NjYL+Xut71B/Qcg0QRNJ0ymoWv2wdO/fbTvS0dCSaxnPMAZ/jMbbg\r\noMLdkWZ4Z9L8BUWxSDlmCWrcgPnWGcXiO7E=\r\n=J7DZ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"elmasse","email":"elmasse@gmail.com"},"directories":{},"maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nextein_4.3.0_1668624298037_0.1449115033809636"},"_hasShrinkwrap":false}},"readme":"# nextein\n\nA static site generator based in Next.js\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/elmasse/nextein/node-ci)\n[![npm](https://img.shields.io/npm/v/nextein)](https://www.npmjs.com/package/nextein)\n\n#### [Site](https://nextein.elmasse.io/) | [Documentation](https://nextein.elmasse.io/docs) | [Guides](https://nextein.elmasse.io/guides)\n\n## What is it?\n`nextein` is  a wrapper around `next.js` that allows you to write static sites using `markdown` and `react`. \n\n### Requirements\n*NodeJS* __v10.x__+ is required to run `nextein` commands.\n\n## Starter Kit\nIf you want to jump into a starter project check [nextein-starter](https://github.com/elmasse/nextein-starter)\n\n## Getting Started\nThere are a few steps you have to follow to get your site up and running with `nextein`\n\n- Create a project:\n    -  `mkdir my-site`\n    -  `cd my-site`\n    -  `npm init -y` \n- Install Dependencies\n    -  `npm i nextein next react react-dom`\n- Add a `next.config.js` config file \n\n    ```js\n    const { withNextein } = require('nextein/config')\n\n    module.exports = withNextein({\n\n    })\n\n    ```\n- Create `pages/index.js`\n\n    ```js\n    import React from 'react'\n\n    import { getPosts } from 'nextein/fetcher'\n    import Content from 'nextein/content'\n\n    export async function getStaticProps () {\n      return {\n        props: {\n          posts: await getPosts()\n        }\n      }\n    }\n\n    export default function Index ({ posts }) {\n      return (\n        <section>\n        {\n          posts.map(post => <Content {...post} />)\n        }\n        </section>\n      )\n    })\n\n    ```\n- Create a `markdown` post entry under `posts` folder (`posts/my-first-post.md`)\n\n    ```md\n    ---\n    title: First Post\n    category: post\n    ---\n\n    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.\n\n    This paragraph should *not* appear in that list.\n\n    ```\n- Add npm scripts to run dev mode to your `package.json`\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\"\n    }\n    ```\n- Run the development server\n    - `npm run dev`\n    - open http://localhost:3000\n\n- Add another npm script to your `package.json` to export the site\n\n    ```json\n    \"scripts\": {\n      \"dev\": \"next\",\n      \"export\": \"next build && next export\"\n    }\n    ```\n\n## Documentation\n\n### `fetcher` \n\nUse fetcher to retrieve the posts and data from your markdown files. \n\nThe `getPostsFilterBy` and `getDataFilterBy` methods in fetcher allows to pass filter functions. For instance, we can use `inCategory` filter to retrieve posts in a given category:\n\n```js\nimport { getPostsFilterBy } from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\n//...\nconst blog = await getPostsFilterBy(InCategory('blog'))\n\n```\n\nThe `getData` and `getDataFilterBy` will retrieve only the metadata generated for entries instead of the entire post.\n\nThe `fetcher` method is a convenient way to define a filter and then use the `getPosts` and `getData` with a filter applied.\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\n//...\nconst { getPosts } = fetcher(InCategory('blog'))\n\n\n//...\nconst blog = await getPosts()\n\n```\n\n\n\nYou can use Dynamic Routes and *static generator functions* (getStaticProps and getStaticPaths) with fetcher methods.\n\nExample for a `[name].js` dynamic route\n\n```js\nimport fetcher from 'nextein/fetcher'\n\nconst { getData, getPost } = fetcher(/* filter */)\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: data.map(({ name }) => ({ params: { name } })),\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const post = await getPost(params)\n  return { props: { post } }\n}\n\nexport default function Post ({ post }) {\n  //...\n}\n\n```\n\nExample for a `[[...name]].js` dynamic route:\n\n```js\nimport fetcher from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\nconst { getData, getPosts, getPost } = fetcher(inCategory('guides'))\n\nexport async function getStaticPaths () {\n  const data = await getData()\n  return {\n    paths: [{ params: { name: [] } },\n      ...data.map(({ name }) => ({ params: { name: [name] } }))\n    ],\n    fallback: false\n  }\n}\n\nexport async function getStaticProps ({ params }) {\n  const posts = await getPosts()\n  const post = await getPost(params) // This can be null if not matching `...name`\n  return { props: { posts, post } }\n}\n\nexport default function Guides ({ posts, post }) {\n  //...\n}\n\n```\n\n### `inCategory(category, options)`\n\nFilter function to be applied to posts to retrieve posts in a given category.\n\n- `category`: `{String}` The category to filter results.\n- `options` : `{Object}` Optional\n    - `includeSubCategories:` `Boolean` true to include posts in sub categories. Default: `false`\n\nCategories are resolved by the folder structure by default. This means that a post located at `posts/categoryA/subOne` will have a category `categoryA/subOne` unless you specify the category name in frontmatter. \n\n```js\nimport { getPosts } from 'nextein/fetcher'\nimport { inCategory } from 'nextein/filters'\n\n//...\n\nconst posts = await getPosts()\nconst homePosts = posts.filter(inCategory('home'))\n  \n\n```\n\nIf you want to retrieve all posts under a certain category, let's say `categoryA` which will include all those under `subOne`, use the options `includeSubCategories: true`. \n\n```js\nimport { inCategory } from 'nextein/filters'\n\nconst categoryAPosts = posts\n  .filter(inCategory('categoryA', { includeSubCategories: true }))\n\n```\n\n### `Content`\n\nComponent to render a `post` object. This component receives the `content` from the post as a property.\nUse the `excerpt` property to only render the first paragraph (this is useful when rendering a list of posts).\n\n- `content`: `{Object}` Markdown content in HAST format to be render. This is provided by `post.content`\n- `excerpt`: `{Boolean}` true to only render the first paragraph. Optional. Default: `false`\n- `renderers`: `{Object}` A set of custom renderers for Markdown elements with the form of `[tagName]: renderer`.\n- `component`: `{String|React.Component}`\tThe component used for the root node.\n\n\n```js\n\nimport Content from 'nextein/content'\n\n//...\n\nexport default function PostPage ({ post }) {\n  return <Content {...post} />\n} \n\n```\n\n\nUsing `renderers` to change/style the `<p>` tag\n\n```js\n\nconst Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )\n\n// Then in your render method ...\n\n  <Content\n    {...post} \n    renderers={{\n      p: Paragraph \n    }}\n  />\n\n```\n\n\n### `post`\n- `__id` is the unique identifier generated by nextein.\n- `data` is the frontmatter object containig the post meta information (title, page, category, etc)\n    - `data.category` is the post's category. When not specified, if the post is inside a folder, the directory structure under `posts` will be used. \n    - `data.date`: JSON date from frontmatter's date or date in file name or file creation date\n- `content` is representation of post content (generally in HAST format) created by the build plugin for a given mimeType.\n\n```js\n\n{ data, content } = post\n\n```\n\n### frontmatter\n\nThere are only a few defined properties in the frontmatter metadata that is used by `nextein`\n\n```md\n---\ncategory: categoryOne\ndate: 2017-06-23\n\n---\n\nPost Content...\n\n```\n\n- `category`: the category name (optional)\n- `date`: date string in YYYY-MM-DD format. Used to sort posts list. (optional)\n- `published`: Set to `false` to remove this post from entries.\n- `name`: **Read Only** The post file name. Date is removed from name if present.\n\n### `withNextein`\n\nA wrapper configuration function to be applied into the `next.config.js`. It provides a way to add your own `next.js` config along with `nextein` internal next.js config.\n\n> next.config.js\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  // Your own next.js config here\n})\n\n```\n\n## Plugins\n\nYou can also define nextein plugins using the `withNextein` configuration:\n\n```js\nconst { withNextein } = require('nextein/config')\n\nmodule.exports = withNextein({\n  nextein: {\n    plugins: [\n      //your nextein plugins here\n    ]\n  }\n  // Your own next.js config here\n})\n\n```\n\nThe `nextein.plugins` configuration accepts an array of plugins with the following formats:\n\n- ` [name] `: Just a string to define the plugin.\n- ` [name, options] `: A string to define the plugin and a plugins options object.\n- ` { name, id, options } `: A plugin object. The `name` field is required. All previous definitoins are transformed into this format. The `id` is optional, when provided allows multiple instances of the same plugin.\n\nThe plugin `name` should be a pre-installed plugin (`nextein-plugin-markdown`) , or a local file (`./myplugins/my-awesome-plugin`)\n\n### Default Plugins\n\nThe default configuration includes:\n\n```js\nplugins: [\n  ['nextein-plugin-source-fs', { path: 'posts', data: { page: 'post' } }],\n  'nextein-plugin-markdown',\n  'nextein-plugin-filter-unpublished'\n]\n\n```\n\n#### nextein-plugin-source-fs\n\nRead files from file system.\n\nOptions:\n\n- `path`: Path to read files from.\n- `data`: Default data to be passed as extra for each entry. Default to `{}`\n- `includes`: Default to `**/*.*`. \n- `ignore`: A set of ignored files. The default list includes:\n  ```js\n  '**/.DS_Store',\n  '**/.gitignore',\n  '**/.npmignore',\n  '**/.babelrc',\n  '**/node_modules',\n  '**/yarn.lock',\n  '**/package-lock.json'\n  ```\n\n#### nextein-plugin-markdown\n\nRender markdown files.\n\nOptions:\n\n- `raw`: Default to `true`. Make this `false` to not add the `raw` content in the post object.\n- `position`: Default to `false`. Make this `true` to add the position info to post content HAST.\n- `rehype`: Default to `[]`. Add a set of plugins for `rehype`\n- `remark`: Default to `[]`. Add a set of plugins for `remark`\n\n#### nextein-plugin-filter-unpublished\n\nFilter posts by using a property to prevent draft / unpublished entries to be displayed.\n\nOptions:\n\n- `field`: Default to`'published'`. Will check if a `field` is present in post `data` and filter if set to `false`.\n\n### Writing Plugins\n\nYou can write your own plugins. There are basically 2 different types (source and transforms). Source plugins will be called to generate the posts entries and then the transform plugins will receive those entries and can modify, filter, append, or transform in anyway the posts list.\n\nSee [plugins & lifecyle design document](./DESIGN.md).\n","maintainers":[{"name":"elmasse","email":"elmasse@gmail.com"}],"time":{"modified":"2022-11-16T18:44:58.318Z","created":"2017-05-28T15:20:28.474Z","0.0.0":"2017-05-28T15:20:28.474Z","1.0.0-beta1":"2017-06-20T01:41:32.037Z","1.0.0-beta2":"2017-06-20T02:32:10.460Z","1.0.0-beta3":"2017-06-20T02:39:36.691Z","1.0.0-beta4":"2017-06-20T02:44:45.798Z","1.0.0-beta5":"2017-06-20T02:46:23.557Z","1.0.0-beta6":"2017-06-20T02:49:12.943Z","1.0.0-beta7":"2017-06-20T23:51:34.731Z","1.0.0-beta8":"2017-06-23T21:29:29.563Z","1.0.0-beta9":"2017-06-25T18:06:10.154Z","1.0.0-beta10":"2017-06-28T01:35:07.417Z","1.0.0-beta11":"2017-06-29T19:22:18.430Z","1.0.0-beta12":"2017-07-02T21:08:10.560Z","1.0.0-beta13":"2017-07-09T22:57:52.637Z","1.0.0-beta14":"2017-07-23T19:09:33.050Z","1.0.0-beta15":"2017-07-23T19:49:40.359Z","1.0.0-beta16":"2017-08-01T00:29:04.469Z","1.0.0-beta17":"2017-08-09T21:09:19.165Z","1.0.0-beta18":"2017-08-13T04:16:27.178Z","1.0.0-beta19":"2017-08-18T01:05:43.845Z","1.0.0-beta20":"2017-09-07T22:38:28.297Z","1.0.0-beta21":"2017-09-19T01:24:18.508Z","1.0.0-beta22":"2017-10-02T18:54:55.847Z","1.0.0-beta23":"2017-10-05T20:53:53.777Z","1.0.0-beta24":"2017-10-10T15:44:05.527Z","1.0.0-beta25":"2017-10-30T15:04:26.723Z","1.0.0-beta26":"2017-11-14T18:09:49.924Z","1.0.0-beta27":"2017-11-15T17:50:13.247Z","1.0.0":"2017-11-25T23:59:17.902Z","1.1.0":"2018-01-30T13:09:18.806Z","1.1.1":"2018-02-02T21:23:02.859Z","1.1.2":"2018-02-03T20:16:35.184Z","1.2.0":"2018-02-05T22:48:33.234Z","1.2.1":"2018-02-18T19:16:24.508Z","1.2.2":"2018-03-04T14:36:43.384Z","1.2.3":"2018-04-17T01:18:47.415Z","1.2.4-beta":"2018-04-28T04:03:08.169Z","1.2.4-beta.1":"2018-04-28T20:20:17.538Z","1.3.0-beta.1":"2018-04-29T03:52:51.561Z","1.3.0-beta.2":"2018-04-29T16:02:35.652Z","1.2.4":"2018-05-01T15:53:23.161Z","1.3.0-beta.3":"2018-05-04T23:59:02.998Z","1.3.0-beta.4":"2018-05-05T00:13:28.179Z","1.3.0-beta.5":"2018-05-13T04:32:31.018Z","1.3.0-beta.6":"2018-05-14T03:22:33.431Z","1.3.0-beta.7":"2018-05-17T03:25:26.508Z","1.3.0-beta.8":"2018-05-19T20:17:15.794Z","1.3.0":"2018-05-21T22:00:41.209Z","1.3.1":"2018-05-22T20:36:47.383Z","2.0.0-beta.0":"2018-06-27T02:19:29.158Z","2.0.0-beta.1":"2018-07-02T22:44:37.162Z","2.0.0-beta.2":"2018-07-03T03:14:44.196Z","2.0.0-beta.3":"2018-07-10T03:21:05.531Z","2.0.0-beta.4":"2018-07-13T03:01:52.620Z","2.0.0-beta.5":"2018-08-01T02:09:08.507Z","2.0.0-beta.6":"2018-09-15T19:07:27.439Z","2.0.0-beta.7":"2018-09-16T14:17:02.576Z","2.0.0-beta.8":"2018-09-22T18:59:13.851Z","2.0.0-beta.9":"2018-09-22T19:35:29.004Z","2.0.0":"2018-10-22T23:09:14.296Z","2.1.0-beta.0":"2018-11-06T23:09:55.212Z","2.1.0-beta.1":"2018-11-07T22:11:20.787Z","2.1.0-beta.2":"2018-11-14T02:33:03.152Z","2.1.0-beta.3":"2018-11-14T03:06:27.432Z","2.1.0-beta.4":"2018-11-18T21:38:35.834Z","2.1.0":"2018-11-18T22:17:31.130Z","2.1.1":"2018-11-21T02:46:51.462Z","2.1.2":"2018-11-21T03:36:22.842Z","2.1.3":"2019-02-12T20:15:30.756Z","2.2.0":"2019-02-28T02:06:43.730Z","2.3.0-beta.0":"2019-07-15T14:20:54.626Z","2.3.0-beta.1":"2019-07-18T21:10:30.782Z","2.3.0":"2019-07-19T01:27:50.671Z","2.3.1":"2019-10-12T14:12:40.698Z","2.3.2":"2019-12-23T12:59:55.152Z","2.3.3":"2019-12-27T20:07:03.485Z","2.3.4":"2020-04-06T15:54:01.709Z","2.4.0-beta.0":"2020-04-09T13:07:46.131Z","2.4.0":"2020-04-12T19:23:37.859Z","2.4.1-beta.0":"2020-04-27T20:21:19.845Z","2.4.1":"2020-04-27T20:37:47.846Z","2.5.0-beta.0":"2020-05-03T20:35:51.716Z","2.5.0":"2020-05-05T19:40:39.161Z","2.5.1":"2020-05-11T13:04:22.754Z","2.6.0-beta.0":"2020-07-17T18:53:47.796Z","2.6.0-beta.1":"2020-07-17T19:01:18.955Z","2.6.0-beta.2":"2020-07-17T19:03:11.145Z","2.6.0-beta.3":"2020-07-17T19:11:48.809Z","2.6.0-beta.4":"2020-07-17T19:14:35.629Z","2.6.0":"2020-07-17T19:49:37.256Z","2.7.0-beta.0":"2020-07-23T17:22:00.610Z","2.7.0":"2020-07-27T18:30:40.997Z","2.7.1":"2020-07-28T21:38:06.390Z","2.7.3":"2020-08-15T18:35:42.988Z","3.0.0-beta.0":"2020-09-03T13:57:39.706Z","3.0.0-beta.1":"2020-09-04T21:02:27.820Z","3.0.0-beta.2":"2020-09-09T14:50:58.787Z","3.0.0-beta.3":"2020-09-10T12:34:00.082Z","3.0.0-beta.4":"2020-09-10T18:20:48.877Z","3.0.0-beta.5":"2020-09-11T11:56:43.404Z","3.0.0-beta.6":"2020-09-15T16:23:03.667Z","3.0.0-beta.7":"2020-09-18T14:34:19.150Z","3.0.0-beta.8":"2020-09-23T13:29:52.266Z","3.0.0-beta.9":"2020-10-05T13:55:05.747Z","3.0.0-beta.10":"2020-10-12T13:23:57.467Z","3.0.0-beta.11":"2020-10-13T12:30:05.504Z","3.0.0-beta.12":"2020-10-14T12:01:07.274Z","3.0.0-beta.13":"2020-10-15T18:28:51.427Z","3.0.0-beta.14":"2020-10-15T19:37:20.562Z","3.0.0-beta.15":"2020-10-16T11:40:32.634Z","3.0.0-beta.16":"2020-10-16T14:14:54.881Z","3.0.0-beta.17":"2020-10-21T16:06:44.189Z","3.0.0-beta.18":"2020-10-27T20:26:46.886Z","3.0.0-beta.19":"2020-10-30T13:43:52.437Z","3.0.0-beta.20":"2020-11-03T17:35:45.881Z","3.0.0-beta.21":"2020-11-04T11:59:01.162Z","3.0.0-beta.22":"2020-11-05T22:03:36.691Z","3.0.0-beta.23":"2020-11-11T11:05:04.878Z","3.0.0-beta.24":"2020-11-11T11:11:38.661Z","3.0.0-beta.25":"2020-11-11T11:25:00.545Z","3.0.0-beta.26":"2020-11-11T11:46:34.603Z","3.0.0-beta.27":"2020-11-16T11:04:30.934Z","3.0.0-beta.28":"2020-11-18T21:28:01.633Z","3.0.0-beta.29":"2020-11-19T20:57:54.642Z","3.0.0-beta.30":"2020-11-20T12:36:49.406Z","3.0.0":"2020-11-20T17:58:53.562Z","3.0.1":"2021-02-23T17:55:09.757Z","3.0.2-beta.0":"2021-06-02T16:51:38.482Z","3.0.2":"2021-06-02T17:08:45.151Z","3.1.0":"2021-06-23T14:08:27.501Z","3.1.1":"2021-06-23T18:48:40.407Z","3.1.2":"2021-06-25T12:17:54.941Z","3.1.3":"2021-07-22T17:40:10.083Z","3.2.0":"2021-08-03T16:19:36.310Z","3.2.1":"2021-09-24T17:48:42.827Z","3.2.2":"2021-09-24T18:50:54.964Z","3.2.3":"2021-09-30T14:50:35.934Z","4.0.0-beta.0":"2021-10-15T15:24:02.147Z","3.2.4":"2021-10-18T13:02:14.717Z","4.0.0-beta.1":"2021-10-18T20:59:11.961Z","4.0.0-beta.2":"2021-10-19T15:38:42.194Z","4.0.0-beta.3":"2021-10-20T12:53:48.639Z","4.0.0-beta.4":"2021-10-20T15:52:29.340Z","4.0.0-beta.5":"2021-11-01T11:58:15.400Z","4.0.0-beta.6":"2021-11-01T12:40:34.551Z","4.0.0-beta.7":"2021-11-01T12:45:10.164Z","4.0.0-beta.8":"2021-11-01T15:39:43.134Z","4.0.0-beta.9":"2021-11-03T15:57:21.428Z","4.0.0-beta.10":"2021-11-04T15:25:59.359Z","3.2.5":"2021-11-04T16:03:23.291Z","4.0.0-beta.11":"2021-11-05T15:18:31.898Z","4.0.0-beta.12":"2021-11-05T17:27:15.596Z","4.0.0":"2022-01-03T15:04:52.648Z","4.0.1":"2022-01-05T11:38:55.896Z","4.0.2":"2022-01-31T11:33:11.065Z","4.0.3":"2022-01-31T14:42:35.979Z","4.0.4":"2022-02-12T22:45:20.047Z","4.0.5":"2022-04-01T21:31:25.647Z","4.1.0":"2022-08-10T19:47:54.619Z","4.1.1":"2022-08-10T20:55:30.858Z","4.2.0":"2022-09-12T15:03:14.549Z","4.3.0":"2022-11-16T18:44:58.236Z"},"keywords":["blog","blog-engine","static","website","next.js","react","markdown","ssr"],"license":"ISC","readmeFilename":"README.md","homepage":"https://nextein.elmasse.io","repository":{"type":"git","url":"git+https://github.com/elmasse/nextein.git"},"author":{"name":"Maximiliano Fierro","email":"elmasse@gmail.com"},"bugs":{"url":"https://github.com/elmasse/nextein/issues"},"users":{"elmasse":true}}