+11
-9
@@ -8,17 +8,19 @@ #!/usr/bin/env node | ||
| console.log(`tinyjam v${version}`); | ||
| if (process.argv.length < 4) { | ||
| console.log('usage: tinyjam <source_dir> <output_dir>'); | ||
| console.log(`tinyjam v${version}`); | ||
| console.log('usage: tinyjam source_dir output_dir [--breaks] [--smartypants]'); | ||
| } else { | ||
| console.log(''); | ||
| const start = performance.now(); | ||
| const [src, out] = process.argv.slice(2).filter(s => !s.startsWith('--')); | ||
| const breaks = process.argv.includes('--breaks'); | ||
| const smartypants = process.argv.includes('--smartypants'); | ||
| const log = !process.argv.includes('--silent'); | ||
| const src = process.argv[2]; | ||
| const out = process.argv[3]; | ||
| tinyjam(src, out); | ||
| if (log) console.log(`tinyjam v${version}\n`); | ||
| const start = performance.now(); | ||
| tinyjam(src, out, {log, breaks, smartypants}); | ||
| const elapsed = performance.now() - start; | ||
| console.log(`\nDone in ${elapsed.toLocaleString()}ms.`); | ||
| if (log) console.log(`\nDone in ${elapsed.toLocaleString()}ms.`); | ||
| } |
+24
-12
@@ -13,9 +13,15 @@ 'use strict'; | ||
| const defaultOptions = { | ||
| log: false, | ||
| breaks: false, | ||
| smartypants: false, | ||
| highlight: null | ||
| }; | ||
| function tinyjam(src, dest, options = {}) { | ||
| fs.mkdirSync(dest, {recursive: true}); // make sure destination exists | ||
| options = Object.assign({}, defaultOptions, options); | ||
| const markedOptions = { // Markdown renderer options | ||
| breaks: options.breaks, | ||
| smartypants: options.smartypants | ||
| }; | ||
| // Markdown renderer options | ||
| const {breaks, smartypants, highlight} = options; | ||
| const markedOptions = {breaks, smartypants, highlight, smartLists: true}; | ||
@@ -28,2 +34,4 @@ const proto = {}; | ||
| fs.mkdirSync(dest, {recursive: true}); // make sure destination exists | ||
| walk(src, root); // process files, collect data and templates to render | ||
@@ -42,5 +50,9 @@ | ||
| function log(msg) { | ||
| if (options.log) console.log(msg); | ||
| } | ||
| function render(template, data, dir, name, ext) { | ||
| const path = join(dir, name) + ext; | ||
| console.log(`render ${path}`); | ||
| log(`render ${path}`); | ||
| fs.writeFileSync(join(dest, path), template(data)); | ||
@@ -74,3 +86,3 @@ } | ||
| if (file[0] === '.' || file === 'node_modules' || ext === '.lock' || name.endsWith('-lock')) { | ||
| console.log(`skip ${shortPath}`); | ||
| log(`skip ${shortPath}`); | ||
| continue; | ||
@@ -89,3 +101,3 @@ } | ||
| if (ext === '.md') { | ||
| console.log(`read ${shortPath}`); | ||
| log(`read ${shortPath}`); | ||
| const {attributes, body} = fm(fs.readFileSync(path, 'utf8')); | ||
@@ -99,3 +111,3 @@ | ||
| } else if (ext === '.yml' || ext === '.yaml') { | ||
| console.log(`read ${shortPath}`); | ||
| log(`read ${shortPath}`); | ||
| data[name] = createCtx(rootPath, yaml.safeLoad(fs.readFileSync(path, 'utf8'))); | ||
@@ -105,6 +117,6 @@ | ||
| if (name[0] === '_') { // skip includes | ||
| console.log(`skip ${shortPath}`); | ||
| log(`skip ${shortPath}`); | ||
| continue; | ||
| } | ||
| console.log(`compile ${shortPath}`); | ||
| log(`compile ${shortPath}`); | ||
| templates.push({ | ||
@@ -120,3 +132,3 @@ data, | ||
| } else { | ||
| console.log(`copy ${shortPath}`); | ||
| log(`copy ${shortPath}`); | ||
| fs.copyFileSync(path, join(dest, shortPath)); | ||
@@ -123,0 +135,0 @@ } |
+7
-3
@@ -8,3 +8,3 @@ { | ||
| }, | ||
| "version": "0.0.2", | ||
| "version": "0.1.0", | ||
| "author": "Vladimir Agafonkin", | ||
@@ -19,7 +19,11 @@ "license": "ISC", | ||
| "devDependencies": { | ||
| "dir-compare": "^2.3.0", | ||
| "eslint": "^7.0.0", | ||
| "eslint-config-mourner": "^3.0.0" | ||
| "eslint-config-mourner": "^3.0.0", | ||
| "rimraf": "^3.0.2", | ||
| "tape": "^5.0.0" | ||
| }, | ||
| "scripts": { | ||
| "test": "eslint *.js" | ||
| "pretest": "eslint *.js test/test.js", | ||
| "test": "node test/test.js" | ||
| }, | ||
@@ -26,0 +30,0 @@ "eslintConfig": { |
+59
-7
@@ -5,4 +5,6 @@ <h1 align="center">tinyjam</h1> | ||
| A bare-bones, zero-configuration **static site generator** that deliberately has **no features**, an experiment in radical simplicity. Essentially a tiny, elegant glue between [EJS templates](https://ejs.co/) and [Markdown](https://spec.commonmark.org/current/) with freeform structure (enabling incremental adoption) and convenient defaults, written in under 120 lines of JavaScript. _Experimental and a work in progress._ | ||
| A bare-bones, zero-configuration **static site generator** that deliberately has **no features**, an experiment in radical simplicity. Essentially a tiny, elegant glue between [EJS templates](https://ejs.co/) and [Markdown](https://github.github.com/gfm/) with freeform structure (enabling incremental adoption) and convenient defaults, written in under 120 lines of JavaScript. | ||
| [](https://github.com/mourner/tinyjam/actions) | ||
| [](https://packagephobia.now.sh/result?p=tinyjam) | ||
| [](https://github.com/mourner/projects) | ||
@@ -38,6 +40,8 @@ | ||
| Browse the [full example](example/). | ||
| Browse the [full example](example/) and see the [generated website](https://mourner.github.io/tinyjam/test/fixtures/example_output/). | ||
| ## Usage | ||
| ## Documentation | ||
| ### Getting started | ||
| ```bash | ||
@@ -48,3 +52,3 @@ npm install -g tinyjam | ||
| ## Documentation | ||
| ### Folders | ||
@@ -76,2 +80,4 @@ **Tinyjam** doesn't impose any folder structure, processing any data files (`*.md` and `*.yml`) and templates (`*.ejs`) it encounters and copying over anything else. | ||
| Markdown is rendered according to the [GitHub Flavored Markdown](https://github.github.com/gfm/) specification. | ||
| ### Templates | ||
@@ -88,5 +94,26 @@ | ||
| - `rootPath` is a relative path to the root of the project — useful as a prefix for links in includes (e.g. `<%= rootPath %>/index.css`). | ||
| - `root` references all of the project's data, which is useful for accessing data outside of the current template's folder. | ||
| - `rootPath` is a relative path to the root of the project — useful as a prefix for links in includes as they may be used on different nesting levels (e.g. `<%= rootPath %>/index.css`). | ||
| - `root` references all of the project's data, which is useful for accessing data in includes or outside of the current template's folder. | ||
| ### Using as a Node.js library | ||
| ```js | ||
| const tinyjam = require('tinyjam'); | ||
| tinyjam(sourceDir, outputDir, { | ||
| log: false, // log the progress (like in the CLI) | ||
| breaks: false, // Markdown: add single line breaks (like in GitHub comments) | ||
| smartypants: false, // Markdown: convert quotes, dashes and ellipses to typographic equivalents | ||
| highlight: null // a code highlighting function: (code, lang) => html | ||
| }); | ||
| ```` | ||
| ### CLI options | ||
| You can pass the following options to the `tinyjam` CLI: | ||
| - `--breaks`: Add single line breaks as `<br>` in Markdown. | ||
| - `--smartypants`: Convert quotes, dashes and ellipses in Markdown to typographic equivalents. | ||
| - `--silent`: Run silently (unless there's an error). | ||
| ## FAQ | ||
@@ -104,2 +131,6 @@ | ||
| #### How fast is Tinyjam? | ||
| Pretty fast. I didn't see a point in benchmarking because most of the time is spent parsing Markdown/YAML and rendering EJS anyway, but corresponding dependencies (`marked`, `js-yaml`, `ejs`) are very well optimized. | ||
| #### Why EJS for templating, and can I use another templating system? | ||
@@ -113,3 +144,3 @@ | ||
| #### How do you make a multilingual website? | ||
| #### How do I make a multilingual website? | ||
@@ -123,1 +154,22 @@ **Tinyjam** gives you freedom to approach this in many different ways, but here's an example: | ||
| ``` | ||
| #### How do I add pagination? | ||
| At the moment, you can't. It's not a great UI pattern anyway — make an archive page with links to all content instead. | ||
| #### How do I do asset optimization, CSS preprocessing, TypeScript transpilation, etc.? | ||
| Do all the preprocessing in the source directory prior to running `tinyjam`. | ||
| #### How do I add code syntax highlighting? | ||
| Here's an example using the `tinyjam` API with [highlight.js](https://highlightjs.org/): | ||
| ```js | ||
| const tinyjam = require('tinyjam'); | ||
| const {highlight} = require('highlight.js'); | ||
| tinyjam(sourceDir, outputDir, { | ||
| highlight: (code, lang) => highlight(lang, code).value | ||
| }); | ||
| ``` |
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
14123
23.94%123
9.82%168
44.83%5
150%