@t8/docsgen 0.1.81 → 0.1.82

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/dist/bin.js CHANGED
@@ -421,8 +421,28 @@ ${navContent}
421
421
  </nav>`;
422
422
  }
423
423
 
424
- // src/bin/getParsedContent.ts
425
- var import_jsdom3 = require("jsdom");
424
+ // src/bin/getTitle.ts
425
+ function getTitle(ctx, { cover, originalContent, withPackageURL } = {}) {
426
+ let { root, name, title: packageTitle, htmlTitle, scope } = ctx;
427
+ if (originalContent && ![name, packageTitle].includes(originalContent.trim()))
428
+ return originalContent;
429
+ if (cover && htmlTitle) return htmlTitle;
430
+ if (packageTitle) {
431
+ let escapedTitle = escapeHTML(packageTitle);
432
+ return withPackageURL ? `<a href="${root}" class="name">${escapedTitle}</a>` : `<span class="name">${escapedTitle}</span>`;
433
+ }
434
+ let scopeMatches = name?.match(/^(@[^/]+)\/?(.*)/);
435
+ if (!scope || !scopeMatches) {
436
+ let escapedName = escapeHTML(name);
437
+ return withPackageURL ? `<a href="${root}" class="name">${escapedName}</a>` : `<span class="name">${escapedName}</span>`;
438
+ }
439
+ let title = `<a href="${scope}" class="scope">${scopeMatches[1]}</a><span class="sep">/</span>`;
440
+ title += withPackageURL ? `<a href="${root}" class="name">${scopeMatches[2]}</a>` : `<span class="name">${scopeMatches[2]}</span>`;
441
+ return title;
442
+ }
443
+
444
+ // src/bin/parsing/getParsedContent.ts
445
+ var import_jsdom4 = require("jsdom");
426
446
  var import_markdown_it = __toESM(require("markdown-it"));
427
447
 
428
448
  // src/bin/getSlug.ts
@@ -436,13 +456,7 @@ function getSlug(title) {
436
456
  return slug;
437
457
  }
438
458
 
439
- // src/bin/getParsedContent.ts
440
- var md = new import_markdown_it.default({
441
- html: true
442
- });
443
- function joinLines(x) {
444
- return x.join("\n").trim();
445
- }
459
+ // src/bin/parsing/buildNav.ts
446
460
  function buildNav(ctx, dom) {
447
461
  let { root, contentDir, singlePage } = ctx;
448
462
  let linkMap = {};
@@ -496,9 +510,13 @@ function buildNav(ctx, dom) {
496
510
  linkMap
497
511
  };
498
512
  }
513
+
514
+ // src/bin/parsing/getInstallationCode.ts
499
515
  function getInstallationCode(element) {
500
516
  return element.querySelector("code")?.innerHTML.trim().match(/(\S\s*)?(npm (i|install) .*)/)?.[2];
501
517
  }
518
+
519
+ // src/bin/parsing/getSectionPostprocess.ts
502
520
  function getSectionPostprocess(linkMap) {
503
521
  return (content) => {
504
522
  let s = content;
@@ -510,6 +528,14 @@ function getSectionPostprocess(linkMap) {
510
528
  return s;
511
529
  };
512
530
  }
531
+
532
+ // src/bin/parsing/joinLines.ts
533
+ function joinLines(x) {
534
+ return x.join("\n").trim();
535
+ }
536
+
537
+ // src/bin/parsing/postprocessBadges.ts
538
+ var import_jsdom3 = require("jsdom");
513
539
  function postprocessBadges(content) {
514
540
  let { document } = new import_jsdom3.JSDOM(content).window;
515
541
  for (let img of document.querySelectorAll("img")) {
@@ -522,11 +548,37 @@ function postprocessBadges(content) {
522
548
  }
523
549
  return document.body.innerHTML;
524
550
  }
551
+
552
+ // src/bin/parsing/preprocessContent.ts
553
+ var marker = {
554
+ show: {
555
+ start: "<!-- docsgen-show-start --",
556
+ end: "-- docsgen-show-end -->"
557
+ },
558
+ hide: {
559
+ start: "<!-- docsgen-hide-start -->",
560
+ end: "<!-- docsgen-hide-end -->"
561
+ }
562
+ };
563
+ function preprocessContent(s) {
564
+ let k0 = -1;
565
+ let k1 = -1;
566
+ while ((k0 = s.indexOf(marker.show.start, k1)) !== -1 && (k1 = s.indexOf(marker.show.end, k0)) !== -1)
567
+ s = `${s.slice(0, k0)}${s.slice(k0 + marker.show.start.length, k1)}${s.slice(k1 + marker.show.end.length)}`;
568
+ while ((k0 = s.indexOf(marker.hide.start, k1)) !== -1 && (k1 = s.indexOf(marker.hide.end, k0)) !== -1)
569
+ s = `${s.slice(0, k0 + marker.show.start.length - 1)}${s.slice(k0 + marker.show.start.length, k1)}${s.slice(k1 + marker.show.end.length + 2)}`;
570
+ return s;
571
+ }
572
+
573
+ // src/bin/parsing/getParsedContent.ts
574
+ var md = new import_markdown_it.default({
575
+ html: true
576
+ });
525
577
  async function getParsedContent(ctx) {
526
578
  let { singlePage, linkMap } = ctx;
527
579
  let rawContent = await fetchText(getLocation(ctx, "README.md", ctx.source));
528
- let content = md.render(rawContent);
529
- let dom = new import_jsdom3.JSDOM(content);
580
+ let content = md.render(preprocessContent(rawContent));
581
+ let dom = new import_jsdom4.JSDOM(content);
530
582
  let { nav, linkMap: navLinkMap } = buildNav(ctx, dom);
531
583
  let badges = [];
532
584
  let title = "";
@@ -608,26 +660,6 @@ async function getParsedContent(ctx) {
608
660
  };
609
661
  }
610
662
 
611
- // src/bin/getTitle.ts
612
- function getTitle(ctx, { cover, originalContent, withPackageURL } = {}) {
613
- let { root, name, title: packageTitle, htmlTitle, scope } = ctx;
614
- if (originalContent && ![name, packageTitle].includes(originalContent.trim()))
615
- return originalContent;
616
- if (cover && htmlTitle) return htmlTitle;
617
- if (packageTitle) {
618
- let escapedTitle = escapeHTML(packageTitle);
619
- return withPackageURL ? `<a href="${root}" class="name">${escapedTitle}</a>` : `<span class="name">${escapedTitle}</span>`;
620
- }
621
- let scopeMatches = name?.match(/^(@[^/]+)\/?(.*)/);
622
- if (!scope || !scopeMatches) {
623
- let escapedName = escapeHTML(name);
624
- return withPackageURL ? `<a href="${root}" class="name">${escapedName}</a>` : `<span class="name">${escapedName}</span>`;
625
- }
626
- let title = `<a href="${scope}" class="scope">${scopeMatches[1]}</a><span class="sep">/</span>`;
627
- title += withPackageURL ? `<a href="${root}" class="name">${scopeMatches[2]}</a>` : `<span class="name">${scopeMatches[2]}</span>`;
628
- return title;
629
- }
630
-
631
663
  // src/bin/toFileContent.ts
632
664
  function toFileContent(x) {
633
665
  let s = x.replace(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t8/docsgen",
3
- "version": "0.1.81",
3
+ "version": "0.1.82",
4
4
  "description": "",
5
5
  "main": "dist/bin.js",
6
6
  "bin": {
@@ -0,0 +1,71 @@
1
+ import type { JSDOM } from "jsdom";
2
+ import type { Context } from "../../types/Context";
3
+ import type { NavItem } from "../../types/NavItem";
4
+ import { getSlug } from "../getSlug";
5
+
6
+ export function buildNav(ctx: Context, dom: JSDOM) {
7
+ let { root, contentDir, singlePage } = ctx;
8
+ let linkMap: Record<string, string> = {};
9
+
10
+ let navItem: NavItem | null = null;
11
+ let nav: NavItem[] = [];
12
+
13
+ if (singlePage)
14
+ navItem = {
15
+ id: "Overview",
16
+ title: "Overview",
17
+ items: [],
18
+ };
19
+
20
+ let headings =
21
+ dom.window.document.body.querySelectorAll("h2, h3, h4, h5, h6");
22
+
23
+ for (let element of headings) {
24
+ let tagName = element.tagName.toLowerCase();
25
+
26
+ let isSectionTitle = tagName === "h2";
27
+ let isSubsectionTitle = tagName === "h3";
28
+ let slug = getSlug(element.textContent);
29
+
30
+ let sectionId = isSectionTitle ? slug : (navItem?.id ?? "");
31
+ let link = `${root}${contentDir}/${sectionId}`;
32
+
33
+ let elementId = element.id || slug.toLowerCase().replace(/_/g, "-");
34
+
35
+ if (elementId)
36
+ linkMap[`#${elementId}`] = `${link}${isSectionTitle ? "" : `#${slug}`}`;
37
+
38
+ if (singlePage && isSectionTitle) {
39
+ if (navItem) {
40
+ element.id = slug;
41
+ navItem.items.push({
42
+ id: slug,
43
+ title: element.innerHTML.trim(),
44
+ });
45
+ }
46
+ } else if (isSectionTitle) {
47
+ if (navItem) nav.push(navItem);
48
+
49
+ navItem = {
50
+ id: slug,
51
+ title: element.innerHTML.trim(),
52
+ items: [],
53
+ };
54
+ } else if (isSubsectionTitle) {
55
+ if (navItem) {
56
+ element.id = slug;
57
+ navItem.items.push({
58
+ id: slug,
59
+ title: element.innerHTML.trim(),
60
+ });
61
+ }
62
+ }
63
+ }
64
+
65
+ if (navItem) nav.push(navItem);
66
+
67
+ return {
68
+ nav,
69
+ linkMap,
70
+ };
71
+ }
@@ -0,0 +1,6 @@
1
+ export function getInstallationCode(element: Element) {
2
+ return element
3
+ .querySelector("code")
4
+ ?.innerHTML.trim()
5
+ .match(/(\S\s*)?(npm (i|install) .*)/)?.[2];
6
+ }
@@ -1,130 +1,23 @@
1
1
  import { JSDOM } from "jsdom";
2
2
  import Markdown from "markdown-it";
3
- import type { Context } from "../types/Context";
4
- import type { NavItem } from "../types/NavItem";
5
- import { fetchText } from "./fetchText";
6
- import { getLocation } from "./getLocation";
7
- import { getSlug } from "./getSlug";
3
+ import type { Context } from "../../types/Context";
4
+ import { fetchText } from "../fetchText";
5
+ import { getLocation } from "../getLocation";
6
+ import { buildNav } from "./buildNav";
7
+ import { getInstallationCode } from "./getInstallationCode";
8
+ import { getSectionPostprocess } from "./getSectionPostprocess";
9
+ import { joinLines } from "./joinLines";
10
+ import { postprocessBadges } from "./postprocessBadges";
11
+ import { preprocessContent } from "./preprocessContent";
8
12
 
9
13
  const md = new Markdown({
10
14
  html: true,
11
15
  });
12
16
 
13
- function joinLines(x: string[]) {
14
- return x.join("\n").trim();
15
- }
16
-
17
- function buildNav(ctx: Context, dom: JSDOM) {
18
- let { root, contentDir, singlePage } = ctx;
19
- let linkMap: Record<string, string> = {};
20
-
21
- let navItem: NavItem | null = null;
22
- let nav: NavItem[] = [];
23
-
24
- if (singlePage)
25
- navItem = {
26
- id: "Overview",
27
- title: "Overview",
28
- items: [],
29
- };
30
-
31
- let headings =
32
- dom.window.document.body.querySelectorAll("h2, h3, h4, h5, h6");
33
-
34
- for (let element of headings) {
35
- let tagName = element.tagName.toLowerCase();
36
-
37
- let isSectionTitle = tagName === "h2";
38
- let isSubsectionTitle = tagName === "h3";
39
- let slug = getSlug(element.textContent);
40
-
41
- let sectionId = isSectionTitle ? slug : (navItem?.id ?? "");
42
- let link = `${root}${contentDir}/${sectionId}`;
43
-
44
- let elementId = element.id || slug.toLowerCase().replace(/_/g, "-");
45
-
46
- if (elementId)
47
- linkMap[`#${elementId}`] = `${link}${isSectionTitle ? "" : `#${slug}`}`;
48
-
49
- if (singlePage && isSectionTitle) {
50
- if (navItem) {
51
- element.id = slug;
52
- navItem.items.push({
53
- id: slug,
54
- title: element.innerHTML.trim(),
55
- });
56
- }
57
- } else if (isSectionTitle) {
58
- if (navItem) nav.push(navItem);
59
-
60
- navItem = {
61
- id: slug,
62
- title: element.innerHTML.trim(),
63
- items: [],
64
- };
65
- } else if (isSubsectionTitle) {
66
- if (navItem) {
67
- element.id = slug;
68
- navItem.items.push({
69
- id: slug,
70
- title: element.innerHTML.trim(),
71
- });
72
- }
73
- }
74
- }
75
-
76
- if (navItem) nav.push(navItem);
77
-
78
- return {
79
- nav,
80
- linkMap,
81
- };
82
- }
83
-
84
- function getInstallationCode(element: Element) {
85
- return element
86
- .querySelector("code")
87
- ?.innerHTML.trim()
88
- .match(/(\S\s*)?(npm (i|install) .*)/)?.[2];
89
- }
90
-
91
- function getSectionPostprocess(linkMap: Record<string, string | undefined>) {
92
- return (content: string) => {
93
- let s = content;
94
-
95
- s = s.replace(/<a href="([^"]+)">/g, (_, url) => {
96
- let nextURL = linkMap[url] ?? url;
97
- let attrs = /^(https?:)?\/\//.test(nextURL) ? ' target="_blank"' : "";
98
-
99
- return `<a href="${nextURL}"${attrs}>`;
100
- });
101
-
102
- return s;
103
- };
104
- }
105
-
106
- function postprocessBadges(content: string) {
107
- let { document } = new JSDOM(content).window;
108
-
109
- for (let img of document.querySelectorAll("img")) {
110
- let parent = img.parentElement;
111
-
112
- if (!parent) continue;
113
-
114
- let container = document.createElement("span");
115
- container.className = "badge";
116
-
117
- parent.insertBefore(container, img);
118
- container.append(img);
119
- }
120
-
121
- return document.body.innerHTML;
122
- }
123
-
124
17
  export async function getParsedContent(ctx: Context) {
125
18
  let { singlePage, linkMap } = ctx;
126
19
  let rawContent = await fetchText(getLocation(ctx, "README.md", ctx.source));
127
- let content = md.render(rawContent);
20
+ let content = md.render(preprocessContent(rawContent));
128
21
  let dom = new JSDOM(content);
129
22
 
130
23
  let { nav, linkMap: navLinkMap } = buildNav(ctx, dom);
@@ -0,0 +1,16 @@
1
+ export function getSectionPostprocess(
2
+ linkMap: Record<string, string | undefined>,
3
+ ) {
4
+ return (content: string) => {
5
+ let s = content;
6
+
7
+ s = s.replace(/<a href="([^"]+)">/g, (_, url) => {
8
+ let nextURL = linkMap[url] ?? url;
9
+ let attrs = /^(https?:)?\/\//.test(nextURL) ? ' target="_blank"' : "";
10
+
11
+ return `<a href="${nextURL}"${attrs}>`;
12
+ });
13
+
14
+ return s;
15
+ };
16
+ }
@@ -0,0 +1,3 @@
1
+ export function joinLines(x: string[]) {
2
+ return x.join("\n").trim();
3
+ }
@@ -0,0 +1,19 @@
1
+ import { JSDOM } from "jsdom";
2
+
3
+ export function postprocessBadges(content: string) {
4
+ let { document } = new JSDOM(content).window;
5
+
6
+ for (let img of document.querySelectorAll("img")) {
7
+ let parent = img.parentElement;
8
+
9
+ if (!parent) continue;
10
+
11
+ let container = document.createElement("span");
12
+ container.className = "badge";
13
+
14
+ parent.insertBefore(container, img);
15
+ container.append(img);
16
+ }
17
+
18
+ return document.body.innerHTML;
19
+ }
@@ -0,0 +1,29 @@
1
+ const marker = {
2
+ show: {
3
+ start: "<!-- docsgen-show-start --",
4
+ end: "-- docsgen-show-end -->",
5
+ },
6
+ hide: {
7
+ start: "<!-- docsgen-hide-start -->",
8
+ end: "<!-- docsgen-hide-end -->",
9
+ },
10
+ };
11
+
12
+ export function preprocessContent(s: string) {
13
+ let k0 = -1;
14
+ let k1 = -1;
15
+
16
+ while (
17
+ (k0 = s.indexOf(marker.show.start, k1)) !== -1 &&
18
+ (k1 = s.indexOf(marker.show.end, k0)) !== -1
19
+ )
20
+ s = `${s.slice(0, k0)}${s.slice(k0 + marker.show.start.length, k1)}${s.slice(k1 + marker.show.end.length)}`;
21
+
22
+ while (
23
+ (k0 = s.indexOf(marker.hide.start, k1)) !== -1 &&
24
+ (k1 = s.indexOf(marker.hide.end, k0)) !== -1
25
+ )
26
+ s = `${s.slice(0, k0 + marker.show.start.length - 1)}${s.slice(k0 + marker.show.start.length, k1)}${s.slice(k1 + marker.show.end.length + 2)}`;
27
+
28
+ return s;
29
+ }
@@ -10,9 +10,9 @@ import { getCounterContent } from "./getCounterContent";
10
10
  import { getIcon } from "./getIcon";
11
11
  import { getInjectedContent } from "./getInjectedContent";
12
12
  import { getNav } from "./getNav";
13
- import { getParsedContent } from "./getParsedContent";
14
13
  import { getRepoLink } from "./getRepoLink";
15
14
  import { getTitle } from "./getTitle";
15
+ import { getParsedContent } from "./parsing/getParsedContent";
16
16
  import { stripHTML } from "./stripHTML";
17
17
  import { toFileContent } from "./toFileContent";
18
18