Skip to content

Commit dc1867a

Browse files
authored
Merge pull request #142 from vivliostyle/feat-excludes-key-readmetadata
feat: Add `excludes` argument to `readMetadata`
2 parents a281d80 + 174c8dd commit dc1867a

File tree

3 files changed

+88
-3
lines changed

3 files changed

+88
-3
lines changed

README.md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,10 +356,11 @@ Read metadata from Markdown frontmatter.
356356

357357
Useful if just want to get the metadata, Markdown parse and metadata typing (for TypeScript) are handled by the VFM side.
358358

359-
`readMetadata(md: string): Metadata`
359+
`readMetadata(md: string, excludes: string[]): Metadata`
360360

361361
- params:
362362
- `md`: `String` Markdown text.
363+
- `excludes`: `String[]` A collection of key names to be ignored by meta processing.
363364
- returns:
364365
- `metadata`: `Metadata` Metadata.
365366

@@ -382,7 +383,39 @@ const metadata = readMetadata(md);
382383
console.log(metadata);
383384
```
384385

385-
About `Metadata`, refer to [VFM](https://vivliostyle.github.io/vfm/#/vfm)'s "Frontmatter" or type information of TypeScript.
386+
About `Metadata` details, refer to [VFM](https://vivliostyle.github.io/vfm/#/vfm)'s "Frontmatter" or type information of TypeScript.
387+
388+
**About `excludes`**
389+
390+
Use this if want to add custom metadata with a third party tool.
391+
392+
Keys that are not defined as VFM are treated as `meta`. If you specify a key name in `excludes`, the key and its data type will be preserved and stored in `excludes` instead of `meta`.
393+
394+
```js
395+
import { readMetadata } from '@vivliostyle/vfm'
396+
397+
const md = `---
398+
title: 'Title'
399+
tags: ['foo', 'bar']
400+
---
401+
`;
402+
403+
const metadata = readMetadata(md, ['tags']);
404+
console.log(metadata);
405+
```
406+
407+
Results:
408+
409+
```js
410+
{
411+
title: 'title',
412+
excludes: {
413+
tags: ['foo', 'bar']
414+
}
415+
}
416+
```
417+
418+
`tags` is stored and retained structure in `excludes` instead of `meta`.
386419

387420
#### User-specified metadata
388421

src/plugins/metadata.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,15 @@ export type Metadata = {
7070
style?: string;
7171
/** `<head>...</head>`, reserved for future use. */
7272
head?: string;
73+
74+
/**
75+
* A set of key-value pairs that are specified in `readMetadata` not to be processed as `<meta>`.
76+
* The data types converted from Frontmatter's YAML are retained.
77+
* Use this if want to add custom metadata with a third party tool.
78+
*/
79+
excludes?: {
80+
[key: string]: any;
81+
};
7382
};
7483

7584
/**
@@ -244,15 +253,27 @@ const readSettings = (data: any): VFMSettings => {
244253

245254
/**
246255
* Read metadata from Markdown frontmatter.
256+
*
257+
* Keys that are not defined as VFM are treated as `meta`. If you specify a key name in `excludes`, the key and its data type will be preserved and stored in `excludes` instead of `meta`.
247258
* @param md Markdown.
259+
* @param excludes A collection of key names to be ignored by meta processing.
248260
* @returns Metadata.
249261
*/
250-
export const readMetadata = (md: string): Metadata => {
262+
export const readMetadata = (md: string, excludes: string[] = []): Metadata => {
251263
const metadata: Metadata = {};
252264
const data = parseMarkdown(md);
253265
const others: Array<Array<Attribute>> = [];
254266

255267
for (const key of Object.keys(data)) {
268+
if (excludes.includes(key)) {
269+
if (!metadata.excludes) {
270+
metadata.excludes = {};
271+
}
272+
273+
metadata.excludes[key] = data[key];
274+
continue;
275+
}
276+
256277
switch (key) {
257278
case 'id':
258279
case 'lang':

tests/metadata.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,3 +504,34 @@ body:
504504
`;
505505
expect(received).toBe(expected);
506506
});
507+
508+
it('Excludes key', () => {
509+
const md = `---
510+
title: "Title"
511+
tags: ["Foo", "Bar"]
512+
---
513+
`;
514+
const received = readMetadata(md, ['tags']);
515+
const expected = {
516+
title: 'Title',
517+
excludes: {
518+
tags: ['Foo', 'Bar'],
519+
},
520+
};
521+
expect(received).toStrictEqual(expected);
522+
});
523+
524+
it('Overwrite key with excludes', () => {
525+
const md = `---
526+
title: ["Foo", "Bar"]
527+
---
528+
`;
529+
// It's not supposed to, but it can be overridden, so we'll test it.
530+
const received = readMetadata(md, ['title']);
531+
const expected = {
532+
excludes: {
533+
title: ['Foo', 'Bar'],
534+
},
535+
};
536+
expect(received).toStrictEqual(expected);
537+
});

0 commit comments

Comments
 (0)