@anthonypena/marked-toc-for-series 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -75,3 +75,7 @@ If defined, a title with an `<h2>` tag will be added, if not defined (undefined
75
75
  #### `series`: the series definition
76
76
 
77
77
  A dictionnary of serie definition.
78
+
79
+ #### `minEntryCount` (optional): the minimum count of element for display the TOC
80
+
81
+ Default: 1
package/dist/index.d.mts CHANGED
@@ -4,6 +4,7 @@ type SeriesDef = Record<string, SerieDef>;
4
4
  interface MarkedTocForSeriesOptions {
5
5
  title?: string | undefined | null;
6
6
  series: SeriesDef;
7
+ minEntryCount?: number;
7
8
  }
8
9
  interface SerieDef {
9
10
  articles: ArticleDef[];
@@ -12,7 +13,7 @@ interface ArticleDef {
12
13
  label: string;
13
14
  url: string;
14
15
  }
15
- declare function markedTocForSeries({ title, series, }: MarkedTocForSeriesOptions): marked.MarkedExtension;
16
+ declare function markedTocForSeries({ title, series, minEntryCount, }: MarkedTocForSeriesOptions): marked.MarkedExtension;
16
17
  interface TocForSeriesToken extends marked.Tokens.Generic {
17
18
  type: 'tocForSeries';
18
19
  serieId: string;
package/dist/index.mjs CHANGED
@@ -183,7 +183,8 @@ var require_dist = __commonJS({
183
183
  var import_fp = __toESM(require_dist());
184
184
  function markedTocForSeries({
185
185
  title,
186
- series
186
+ series,
187
+ minEntryCount = 1
187
188
  }) {
188
189
  return {
189
190
  extensions: [
@@ -210,7 +211,7 @@ function markedTocForSeries({
210
211
  return false;
211
212
  }
212
213
  const serie = series[token.serieId];
213
- if ((0, import_fp.isNotDefined)(serie) || (0, import_fp.isNotDefinedOrEmpty)(serie.articles)) {
214
+ if ((0, import_fp.isNotDefined)(serie) || (0, import_fp.isNotDefinedOrEmpty)(serie.articles) || serie.articles.length < minEntryCount) {
214
215
  return "";
215
216
  }
216
217
  const titleHtml = (0, import_fp.isDefinedAndNotEmpty)(title) ? `<h2>${title}</h2>` : void 0;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../fp/dist/basic.js","../../fp/dist/predicates.js","../../fp/dist/clone.js","../../fp/dist/equality.js","../../fp/dist/index.js","../src/marked-toc-for-series.ts"],"sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.notf = exports.not = exports.identity = exports.noop = void 0;\nfunction noop() { }\nexports.noop = noop;\nfunction identity(x) {\n return x;\n}\nexports.identity = identity;\nfunction not(x) {\n return !x;\n}\nexports.not = not;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction notf(f) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return ((...args) => not(f(...args)));\n}\nexports.notf = notf;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isNotDefinedOrEmpty = exports.isDefinedAndNotEmpty = exports.isNotEmpty = exports.isEmpty = exports.isNotDefined = exports.isDefined = void 0;\nfunction isDefined(x) {\n return x != undefined;\n}\nexports.isDefined = isDefined;\nfunction isNotDefined(x) {\n return x == undefined;\n}\nexports.isNotDefined = isNotDefined;\nfunction isEmpty(x) {\n return x.length === 0;\n}\nexports.isEmpty = isEmpty;\nfunction isNotEmpty(x) {\n return x.length > 0;\n}\nexports.isNotEmpty = isNotEmpty;\nfunction isDefinedAndNotEmpty(x) {\n return isDefined(x) && isNotEmpty(x);\n}\nexports.isDefinedAndNotEmpty = isDefinedAndNotEmpty;\nfunction isNotDefinedOrEmpty(x) {\n return isNotDefined(x) || isEmpty(x);\n}\nexports.isNotDefinedOrEmpty = isNotDefinedOrEmpty;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.deepClone = void 0;\nconst predicates_1 = require(\"./predicates\");\nfunction deepClone(x) {\n if (x instanceof Date) {\n return new Date(x.getTime());\n }\n if (typeof x === 'bigint') {\n return BigInt(x.toString());\n }\n if ((0, predicates_1.isNotDefined)(x) ||\n typeof x === 'boolean' ||\n typeof x === 'number' ||\n x === Number.NEGATIVE_INFINITY ||\n x === Number.POSITIVE_INFINITY) {\n return x;\n }\n if (Array.isArray(x)) {\n return x.map(deepClone);\n }\n if (typeof x === 'object') {\n return Object.fromEntries(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Object.entries(x).map(([k, v]) => [\n k,\n deepClone(v),\n ]));\n }\n return JSON.parse(JSON.stringify(x));\n}\nexports.deepClone = deepClone;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isDifferent = exports.isEqual = void 0;\nconst basic_1 = require(\"./basic\");\nfunction isEqual(a, b) {\n if (typeof a !== typeof b) {\n return false;\n }\n if (typeof a === 'boolean' ||\n typeof a === 'number' ||\n typeof a === 'function' ||\n typeof a === 'string' ||\n typeof a === 'undefined' ||\n a === null) {\n return a === b;\n }\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n let aa = a;\n let bb = b;\n if (typeof a === 'bigint') {\n aa = a.toString();\n }\n if (typeof b === 'bigint') {\n bb = b.toString();\n }\n return JSON.stringify(aa) === JSON.stringify(bb);\n}\nexports.isEqual = isEqual;\nfunction isDifferent(a, b) {\n return (0, basic_1.not)(isEqual(a, b));\n}\nexports.isDifferent = isDifferent;\n","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n__exportStar(require(\"./basic\"), exports);\n__exportStar(require(\"./clone\"), exports);\n__exportStar(require(\"./equality\"), exports);\n__exportStar(require(\"./predicates\"), exports);\n","import { marked } from 'marked';\nimport {\n isDefined,\n isDefinedAndNotEmpty,\n isNotDefined,\n isNotDefinedOrEmpty,\n} from '@anthonypena/fp';\n\nexport type SeriesDef = Record<string, SerieDef>;\n\nexport interface MarkedTocForSeriesOptions {\n title?: string | undefined | null;\n series: SeriesDef;\n}\n\nexport interface SerieDef {\n articles: ArticleDef[];\n}\n\nexport interface ArticleDef {\n label: string;\n url: string;\n}\n\nexport function markedTocForSeries({\n title,\n series,\n}: MarkedTocForSeriesOptions): marked.MarkedExtension {\n return {\n extensions: [\n {\n name: 'tocForSeries',\n level: 'block',\n start(src) {\n return src.match(/<!-- TOC-SERIE:.* -->/)?.index;\n },\n tokenizer(src): TocForSeriesToken | undefined {\n const match = /^<!-- TOC-SERIE:(.*) -->?/.exec(src);\n if (isDefined(match)) {\n const type = 'tocForSeries';\n const raw = src.slice(0, src.indexOf('-->') + 3);\n const serieId = match?.[1];\n const token: TocForSeriesToken = { type, raw, serieId };\n return token;\n }\n return undefined;\n },\n renderer(token) {\n if (!isTocForSeriesToken(token)) {\n return false;\n }\n const serie = series[token.serieId];\n if (isNotDefined(serie) || isNotDefinedOrEmpty(serie.articles)) {\n return '';\n }\n\n const titleHtml = isDefinedAndNotEmpty(title)\n ? `<h2>${title}</h2>`\n : undefined;\n return rows(\n `<nav data-serie=\"${token.serieId}\">`,\n titleHtml,\n '<ul>',\n ...serie.articles.map(\n (article) =>\n `<li><a href=\"${article.url}\">${article.label}</a></li>`,\n ),\n '</ul>',\n '</nav>',\n );\n },\n },\n ],\n };\n}\n\ninterface TocForSeriesToken extends marked.Tokens.Generic {\n type: 'tocForSeries';\n serieId: string;\n raw: string;\n}\n\nexport function isTocForSeriesToken(\n token: TocForSeriesToken | { type: unknown },\n): token is TocForSeriesToken {\n return token.type === 'tocForSeries';\n}\n\nfunction rows(...s: (string | undefined | null)[]): string {\n return s.filter(isDefinedAndNotEmpty).join('\\n') + '\\n';\n}\n"],"mappings":"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","names":["isDefined","isNotDefined","isDefinedAndNotEmpty","isNotDefinedOrEmpty","exports"]}
1
+ {"version":3,"sources":["../../fp/dist/basic.js","../../fp/dist/predicates.js","../../fp/dist/clone.js","../../fp/dist/equality.js","../../fp/dist/index.js","../src/marked-toc-for-series.ts"],"sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.notf = exports.not = exports.identity = exports.noop = void 0;\nfunction noop() { }\nexports.noop = noop;\nfunction identity(x) {\n return x;\n}\nexports.identity = identity;\nfunction not(x) {\n return !x;\n}\nexports.not = not;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction notf(f) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return ((...args) => not(f(...args)));\n}\nexports.notf = notf;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isNotDefinedOrEmpty = exports.isDefinedAndNotEmpty = exports.isNotEmpty = exports.isEmpty = exports.isNotDefined = exports.isDefined = void 0;\nfunction isDefined(x) {\n return x != undefined;\n}\nexports.isDefined = isDefined;\nfunction isNotDefined(x) {\n return x == undefined;\n}\nexports.isNotDefined = isNotDefined;\nfunction isEmpty(x) {\n return x.length === 0;\n}\nexports.isEmpty = isEmpty;\nfunction isNotEmpty(x) {\n return x.length > 0;\n}\nexports.isNotEmpty = isNotEmpty;\nfunction isDefinedAndNotEmpty(x) {\n return isDefined(x) && isNotEmpty(x);\n}\nexports.isDefinedAndNotEmpty = isDefinedAndNotEmpty;\nfunction isNotDefinedOrEmpty(x) {\n return isNotDefined(x) || isEmpty(x);\n}\nexports.isNotDefinedOrEmpty = isNotDefinedOrEmpty;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.deepClone = void 0;\nconst predicates_1 = require(\"./predicates\");\nfunction deepClone(x) {\n if (x instanceof Date) {\n return new Date(x.getTime());\n }\n if (typeof x === 'bigint') {\n return BigInt(x.toString());\n }\n if ((0, predicates_1.isNotDefined)(x) ||\n typeof x === 'boolean' ||\n typeof x === 'number' ||\n x === Number.NEGATIVE_INFINITY ||\n x === Number.POSITIVE_INFINITY) {\n return x;\n }\n if (Array.isArray(x)) {\n return x.map(deepClone);\n }\n if (typeof x === 'object') {\n return Object.fromEntries(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Object.entries(x).map(([k, v]) => [\n k,\n deepClone(v),\n ]));\n }\n return JSON.parse(JSON.stringify(x));\n}\nexports.deepClone = deepClone;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isDifferent = exports.isEqual = void 0;\nconst basic_1 = require(\"./basic\");\nfunction isEqual(a, b) {\n if (typeof a !== typeof b) {\n return false;\n }\n if (typeof a === 'boolean' ||\n typeof a === 'number' ||\n typeof a === 'function' ||\n typeof a === 'string' ||\n typeof a === 'undefined' ||\n a === null) {\n return a === b;\n }\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n let aa = a;\n let bb = b;\n if (typeof a === 'bigint') {\n aa = a.toString();\n }\n if (typeof b === 'bigint') {\n bb = b.toString();\n }\n return JSON.stringify(aa) === JSON.stringify(bb);\n}\nexports.isEqual = isEqual;\nfunction isDifferent(a, b) {\n return (0, basic_1.not)(isEqual(a, b));\n}\nexports.isDifferent = isDifferent;\n","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n__exportStar(require(\"./basic\"), exports);\n__exportStar(require(\"./clone\"), exports);\n__exportStar(require(\"./equality\"), exports);\n__exportStar(require(\"./predicates\"), exports);\n","import { marked } from 'marked';\nimport {\n isDefined,\n isDefinedAndNotEmpty,\n isNotDefined,\n isNotDefinedOrEmpty,\n} from '@anthonypena/fp';\n\nexport type SeriesDef = Record<string, SerieDef>;\n\nexport interface MarkedTocForSeriesOptions {\n title?: string | undefined | null;\n series: SeriesDef;\n minEntryCount?: number;\n}\n\nexport interface SerieDef {\n articles: ArticleDef[];\n}\n\nexport interface ArticleDef {\n label: string;\n url: string;\n}\n\nexport function markedTocForSeries({\n title,\n series,\n minEntryCount = 1,\n}: MarkedTocForSeriesOptions): marked.MarkedExtension {\n return {\n extensions: [\n {\n name: 'tocForSeries',\n level: 'block',\n start(src) {\n return src.match(/<!-- TOC-SERIE:.* -->/)?.index;\n },\n tokenizer(src): TocForSeriesToken | undefined {\n const match = /^<!-- TOC-SERIE:(.*) -->?/.exec(src);\n if (isDefined(match)) {\n const type = 'tocForSeries';\n const raw = src.slice(0, src.indexOf('-->') + 3);\n const serieId = match?.[1];\n const token: TocForSeriesToken = { type, raw, serieId };\n return token;\n }\n return undefined;\n },\n renderer(token) {\n if (!isTocForSeriesToken(token)) {\n return false;\n }\n const serie = series[token.serieId];\n if (\n isNotDefined(serie) ||\n isNotDefinedOrEmpty(serie.articles) ||\n serie.articles.length < minEntryCount\n ) {\n return '';\n }\n\n const titleHtml = isDefinedAndNotEmpty(title)\n ? `<h2>${title}</h2>`\n : undefined;\n return rows(\n `<nav data-serie=\"${token.serieId}\">`,\n titleHtml,\n '<ul>',\n ...serie.articles.map(\n (article) =>\n `<li><a href=\"${article.url}\">${article.label}</a></li>`,\n ),\n '</ul>',\n '</nav>',\n );\n },\n },\n ],\n };\n}\n\ninterface TocForSeriesToken extends marked.Tokens.Generic {\n type: 'tocForSeries';\n serieId: string;\n raw: string;\n}\n\nexport function isTocForSeriesToken(\n token: TocForSeriesToken | { type: unknown },\n): token is TocForSeriesToken {\n return token.type === 'tocForSeries';\n}\n\nfunction rows(...s: (string | undefined | null)[]): string {\n return s.filter(isDefinedAndNotEmpty).join('\\n') + '\\n';\n}\n"],"mappings":"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","names":["isDefined","isNotDefined","isDefinedAndNotEmpty","isNotDefinedOrEmpty","exports"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anthonypena/marked-toc-for-series",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "Plugin add table of content for series of urls.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,55 +1,130 @@
1
1
  import { Marked } from 'marked';
2
2
  import { describe, expect, it } from 'vitest';
3
3
 
4
- import { markedTocForSeries } from './marked-toc-for-series';
4
+ import {
5
+ markedTocForSeries,
6
+ MarkedTocForSeriesOptions,
7
+ } from './marked-toc-for-series';
5
8
 
6
9
  describe(markedTocForSeries.name, () => {
7
10
  it.each([
8
11
  [
9
12
  '<!-- TOC-SERIE:some -->',
10
- undefined,
11
13
  {
12
- some: {
13
- articles: [
14
- { label: 'foo', url: 'http://example.com/foo' },
15
- { label: 'bar baz', url: 'http://example.com/bar-baz' },
16
- ],
14
+ title: undefined,
15
+ series: {
16
+ some: {
17
+ articles: [
18
+ { label: 'foo', url: 'http://example.com/foo' },
19
+ { label: 'bar baz', url: 'http://example.com/bar-baz' },
20
+ ],
21
+ },
17
22
  },
18
23
  },
19
24
  '<nav data-serie="some">\n<ul>\n<li><a href="http://example.com/foo">foo</a></li>\n<li><a href="http://example.com/bar-baz">bar baz</a></li>\n</ul>\n</nav>\n',
20
25
  ],
21
26
  [
22
27
  '<!-- TOC-SERIE:serie-id-with-dash -->',
23
- 'Serie',
24
28
  {
25
- 'serie-id-with-dash': {
26
- articles: [
27
- { label: 'foo', url: 'http://example.com/foo' },
28
- { label: 'bar baz', url: 'http://example.com/bar-baz' },
29
- ],
29
+ title: 'Serie',
30
+ series: {
31
+ 'serie-id-with-dash': {
32
+ articles: [
33
+ { label: 'foo', url: 'http://example.com/foo' },
34
+ { label: 'bar baz', url: 'http://example.com/bar-baz' },
35
+ ],
36
+ },
30
37
  },
31
38
  },
32
39
  '<nav data-serie="serie-id-with-dash">\n<h2>Serie</h2>\n<ul>\n<li><a href="http://example.com/foo">foo</a></li>\n<li><a href="http://example.com/bar-baz">bar baz</a></li>\n</ul>\n</nav>\n',
33
40
  ],
34
41
  [
35
42
  '<!-- TOC-SERIE:serie_id_with_underscore -->',
36
- 'Série',
37
43
  {
38
- serie_id_with_underscore: {
39
- articles: [
40
- { label: 'foo', url: 'http://example.com/foo' },
41
- { label: 'bar baz', url: 'http://example.com/bar-baz' },
42
- ],
44
+ title: 'Série',
45
+ series: {
46
+ serie_id_with_underscore: {
47
+ articles: [
48
+ { label: 'foo', url: 'http://example.com/foo' },
49
+ { label: 'bar baz', url: 'http://example.com/bar-baz' },
50
+ ],
51
+ },
43
52
  },
44
53
  },
45
54
  '<nav data-serie="serie_id_with_underscore">\n<h2>Série</h2>\n<ul>\n<li><a href="http://example.com/foo">foo</a></li>\n<li><a href="http://example.com/bar-baz">bar baz</a></li>\n</ul>\n</nav>\n',
46
55
  ],
47
- ['<!-- TOC-SERIE:empty -->', 'Yolo', { empty: { articles: [] } }, ''],
48
- ['<!-- TOC-SERIE:not-existing -->', '', { some: { articles: [] } }, ''],
49
- ])('should create TOC "%s"', (md, title, series, html) => {
50
- const marked = new Marked({ headerIds: false, mangle: false });
51
- marked.use(markedTocForSeries({ title, series }));
56
+ [
57
+ '<!-- TOC-SERIE:empty -->',
58
+ { title: 'Yolo', series: { empty: { articles: [] } } },
59
+ '',
60
+ ],
61
+ [
62
+ '<!-- TOC-SERIE:not-existing -->',
63
+ { title: '', series: { some: { articles: [] } } },
64
+ '',
65
+ ],
66
+ [
67
+ '<!-- TOC-SERIE:under-min-0-2 -->',
68
+ {
69
+ title: '',
70
+ series: { 'under-min-0-2': { articles: [] } },
71
+ minEntryCount: 2,
72
+ },
73
+ '',
74
+ ],
75
+ [
76
+ '<!-- TOC-SERIE:under-min-1-2 -->',
77
+ {
78
+ title: 'Série',
79
+ series: {
80
+ 'under-min-1-2': {
81
+ articles: [{ label: 'foo', url: 'http://example.com/foo' }],
82
+ },
83
+ },
84
+ minEntryCount: 2,
85
+ },
86
+ '',
87
+ ],
88
+ [
89
+ '<!-- TOC-SERIE:equal-min-2-2 -->',
90
+ {
91
+ title: 'Série',
92
+ series: {
93
+ 'equal-min-2-2': {
94
+ articles: [
95
+ { label: 'foo', url: 'http://example.com/foo' },
96
+ { label: 'bar baz', url: 'http://example.com/bar-baz' },
97
+ ],
98
+ },
99
+ },
100
+ minEntryCount: 2,
101
+ },
102
+ '<nav data-serie="equal-min-2-2">\n<h2>Série</h2>\n<ul>\n<li><a href="http://example.com/foo">foo</a></li>\n<li><a href="http://example.com/bar-baz">bar baz</a></li>\n</ul>\n</nav>\n',
103
+ ],
104
+ [
105
+ '<!-- TOC-SERIE:over-min-3-2 -->',
106
+ {
107
+ title: 'Série',
108
+ series: {
109
+ 'over-min-3-2': {
110
+ articles: [
111
+ { label: 'foo', url: 'http://example.com/foo' },
112
+ { label: 'bar baz', url: 'http://example.com/bar-baz' },
113
+ { label: 'baz', url: 'http://example.com/baz' },
114
+ ],
115
+ },
116
+ },
117
+ minEntryCount: 2,
118
+ },
119
+ '<nav data-serie="over-min-3-2">\n<h2>Série</h2>\n<ul>\n<li><a href="http://example.com/foo">foo</a></li>\n<li><a href="http://example.com/bar-baz">bar baz</a></li>\n<li><a href="http://example.com/baz">baz</a></li>\n</ul>\n</nav>\n',
120
+ ],
121
+ ])(
122
+ 'should create TOC "%s"',
123
+ (md: string, options: MarkedTocForSeriesOptions, html: string) => {
124
+ const marked = new Marked({ headerIds: false, mangle: false });
125
+ marked.use(markedTocForSeries(options));
52
126
 
53
- expect(marked.parse(md)).toBe(html);
54
- });
127
+ expect(marked.parse(md)).toBe(html);
128
+ },
129
+ );
55
130
  });
@@ -11,6 +11,7 @@ export type SeriesDef = Record<string, SerieDef>;
11
11
  export interface MarkedTocForSeriesOptions {
12
12
  title?: string | undefined | null;
13
13
  series: SeriesDef;
14
+ minEntryCount?: number;
14
15
  }
15
16
 
16
17
  export interface SerieDef {
@@ -25,6 +26,7 @@ export interface ArticleDef {
25
26
  export function markedTocForSeries({
26
27
  title,
27
28
  series,
29
+ minEntryCount = 1,
28
30
  }: MarkedTocForSeriesOptions): marked.MarkedExtension {
29
31
  return {
30
32
  extensions: [
@@ -50,7 +52,11 @@ export function markedTocForSeries({
50
52
  return false;
51
53
  }
52
54
  const serie = series[token.serieId];
53
- if (isNotDefined(serie) || isNotDefinedOrEmpty(serie.articles)) {
55
+ if (
56
+ isNotDefined(serie) ||
57
+ isNotDefinedOrEmpty(serie.articles) ||
58
+ serie.articles.length < minEntryCount
59
+ ) {
54
60
  return '';
55
61
  }
56
62