@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 +4 -0
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +3 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/marked-toc-for-series.spec.ts +101 -26
- package/src/marked-toc-for-series.ts +7 -1
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;
|
package/dist/index.mjs.map
CHANGED
|
@@ -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,55 +1,130 @@
|
|
|
1
1
|
import { Marked } from 'marked';
|
|
2
2
|
import { describe, expect, it } from 'vitest';
|
|
3
3
|
|
|
4
|
-
import {
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
'
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
[
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
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 (
|
|
55
|
+
if (
|
|
56
|
+
isNotDefined(serie) ||
|
|
57
|
+
isNotDefinedOrEmpty(serie.articles) ||
|
|
58
|
+
serie.articles.length < minEntryCount
|
|
59
|
+
) {
|
|
54
60
|
return '';
|
|
55
61
|
}
|
|
56
62
|
|