Skip to content

Commit

Permalink
Resolves #63: provides a render option allowing usage of any markdown…
Browse files Browse the repository at this point in the history
… parser.
  • Loading branch information
webketje committed Feb 1, 2023
1 parent 235df4b commit 509e24c
Show file tree
Hide file tree
Showing 6 changed files with 251 additions and 15 deletions.
24 changes: 18 additions & 6 deletions lib/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { marked } from 'marked';
import Metalsmith from 'metalsmith';
import { marked } from "marked";
import { Plugin } from "metalsmith";
export type EngineOptions<T = marked.MarkedOptions> = T;

export default markdown;
export interface Options {
export type Render<E> = (source: string, engineOptions: EngineOptions<E>, context: {
path: string;
key: string;
}) => string;

export type Options<E = marked.MarkedOptions> = {
/**
* - Key names of file metadata to render to HTML - can be nested
*/
Expand All @@ -12,11 +18,17 @@ export interface Options {
*/
wildcard?: boolean;
/**
* Marked markdown [options](https://marked.js.org/using_advanced#options)
* - Specify a custom render function with the signature `(source, engineOptions, context) => string`.
* `context` is an object with a `path` key containing the current file path, and `key` containing the target key.
*/
render?: Render<E>;
/**
* Options to pass to the markdown engine (default [marked](https://github.com/markedjs/marked))
*/
engineOptions?: marked.MarkedOptions
engineOptions?: EngineOptions<E>;
};

/**
* A Metalsmith plugin to render markdown files to HTML
*/
declare function markdown(options?: Options): Metalsmith.Plugin;
declare function markdown<E = marked.MarkedOptions>(options?: Options<E>): Plugin;
162 changes: 162 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,15 @@
"marked": "^4.2.4"
},
"devDependencies": {
"@types/markdown-it": "^12.2.3",
"@types/marked": "^4.0.8",
"assert-dir-equal": "^1.1.0",
"auto-changelog": "^2.4.0",
"eslint": "^8.30.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-n": "^15.6.0",
"markdown-it": "^13.0.1",
"metalsmith": "^2.5.0",
"microbundle": "^0.15.1",
"mocha": "^9.2.2",
Expand Down
30 changes: 21 additions & 9 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,30 @@ import { dset as set } from 'dset'
import { marked } from 'marked'
import expandWildcardKeypaths from './expand-wildcard-keypath.js'

function render(data, key, options) {
const value = get(data, key)
if (typeof value === 'string') {
set(data, key, marked(value, options))
}
function defaultRender(source, options) {
return marked(source, options)
}

/**
* @callback Render
* @param {string} source
* @param {Object} engineOptions
* @param {{ path: string, key: string}} context
*/

/**
* @typedef Options
* @property {string[]} [keys] - Key names of file metadata to render to HTML - can be nested
* @property {boolean} [wildcard=false] - Expand `*` wildcards in keypaths
* @property {Render} [render] - Specify a custom render function with the signature `(source, engineOptions, context) => string`.
* `context` is an object with a `path` key containing the current file path, and `key` containing the target key.
* @property {Object} [engineOptions] Options to pass to the markdown engine (default [marked](https://github.com/markedjs/marked))
**/

const defaultOptions = {
keys: [],
wildcard: false,
render: defaultRender,
engineOptions: {}
}

Expand Down Expand Up @@ -65,16 +72,21 @@ function markdown(options = defaultOptions) {
if ('.' != dir) html = join(dir, html)

debug.info('Rendering file "%s" as "%s"', file, html)
const str = marked(data.contents.toString(), options.engineOptions)
const str = options.render(data.contents.toString(), options.engineOptions, { path: file, key: 'contents' })
data.contents = Buffer.from(str)

let keys = options.keys
if (options.wildcard) {
keys = expandWildcardKeypaths(data, options.keys, '*')
}
keys.forEach((k) => {
debug.info('Rendering key "%s" of file "%s"', k.join ? k.join('.') : k, file)
render(data, k, options.engineOptions)
keys.forEach((key) => {
const value = get(data, key)
if (typeof value === 'string') {
debug.info('Rendering key "%s" of file "%s"', key.join ? key.join('.') : key, file)
set(data, key, options.render(value, options.engineOptions, { path: file, key }))
} else {
debug.warn('Couldn\'t render key %s of file "%s": not a string', key.join ? key.join('.') : key, file)
}
})

delete files[file]
Expand Down
Loading

0 comments on commit 509e24c

Please sign in to comment.