@t8/docsgen 0.4.14 → 0.4.16
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 +194 -122
- package/dist/css/index.css +20 -232
- package/package.json +1 -1
- package/src/bin/cleanup.ts +3 -3
- package/src/bin/content/getIndexContent.ts +21 -40
- package/src/bin/content/getSectionContent.ts +0 -3
- package/src/bin/content/getStartContent.ts +6 -4
- package/src/bin/getConfig.ts +1 -1
- package/src/bin/setContent.ts +3 -4
- package/src/css/index.css +20 -232
package/dist/bin.js
CHANGED
|
@@ -241,7 +241,7 @@ async function getConfig() {
|
|
|
241
241
|
config = {
|
|
242
242
|
mainBranch: "main",
|
|
243
243
|
root: "/",
|
|
244
|
-
contentDir: "
|
|
244
|
+
contentDir: "docs",
|
|
245
245
|
...localConfig,
|
|
246
246
|
...(0, import_args_json.parseArgs)(args)
|
|
247
247
|
};
|
|
@@ -266,10 +266,10 @@ import { promisify as promisify2 } from "node:util";
|
|
|
266
266
|
// src/bin/cleanup.ts
|
|
267
267
|
import { rm } from "node:fs/promises";
|
|
268
268
|
import { join } from "node:path";
|
|
269
|
-
async function cleanup({ dir = "" }) {
|
|
269
|
+
async function cleanup({ dir = "", contentDir }) {
|
|
270
270
|
await Promise.all(
|
|
271
|
-
[
|
|
272
|
-
return rm(join(dir, path), { force: true, recursive: true });
|
|
271
|
+
[contentDir, "index.html"].map((path) => {
|
|
272
|
+
return path && rm(join(dir, path), { force: true, recursive: true });
|
|
273
273
|
})
|
|
274
274
|
);
|
|
275
275
|
}
|
|
@@ -325,105 +325,6 @@ function escapeHTML(x) {
|
|
|
325
325
|
return s;
|
|
326
326
|
}
|
|
327
327
|
|
|
328
|
-
// src/bin/content/getCounterContent.ts
|
|
329
|
-
function getCounterContent({ ymid }) {
|
|
330
|
-
if (!ymid) return "";
|
|
331
|
-
return `
|
|
332
|
-
<script>
|
|
333
|
-
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
|
334
|
-
m[i].l=1*new Date();
|
|
335
|
-
for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
|
|
336
|
-
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
|
337
|
-
(window, document, "script", "https://mc.yandex.com/metrika/tag.js", "ym");
|
|
338
|
-
ym(${ymid}, "init", {clickmap: true, trackLinks: true, accurateTrackBounce: true});
|
|
339
|
-
</script>
|
|
340
|
-
<noscript><div><img src="https://mc.yandex.com/watch/${ymid}" style="position:absolute;left:-9999px;" alt=""></div></noscript>
|
|
341
|
-
`.trim();
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
// src/bin/content/getIcon.ts
|
|
345
|
-
var iconTypeMap = {
|
|
346
|
-
ico: "image/x-icon",
|
|
347
|
-
svg: "image/svg+xml",
|
|
348
|
-
png: "image/png",
|
|
349
|
-
gif: "image/gif",
|
|
350
|
-
jpg: "image/jpeg",
|
|
351
|
-
jpeg: "image/jpeg"
|
|
352
|
-
};
|
|
353
|
-
function getIcon({ favicon, faviconType }) {
|
|
354
|
-
let icon = {
|
|
355
|
-
url: favicon,
|
|
356
|
-
type: faviconType
|
|
357
|
-
};
|
|
358
|
-
if (icon.url && !icon.type) {
|
|
359
|
-
let ext = icon.url.split("/").at(-1)?.split(".").at(-1)?.toLowerCase();
|
|
360
|
-
if (ext) icon.type = iconTypeMap[ext];
|
|
361
|
-
}
|
|
362
|
-
return icon;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// src/bin/content/getIconTag.ts
|
|
366
|
-
function getIconTag(ctx) {
|
|
367
|
-
let { url, type } = getIcon(ctx);
|
|
368
|
-
return url ? `<link rel="icon"${type ? ` type="${type}"` : ""} href="${url}">` : "";
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
// src/bin/content/getInjectedContent.ts
|
|
372
|
-
function getInjectedContent(ctx, page, target, mode) {
|
|
373
|
-
let injectedContent = ctx[mode]?.[target];
|
|
374
|
-
if (!injectedContent) return "";
|
|
375
|
-
return (Array.isArray(injectedContent) ? injectedContent : [injectedContent]).reduce((s, item) => {
|
|
376
|
-
if (item === void 0) return s;
|
|
377
|
-
if (typeof item === "string") return `${s}${s ? "\n" : ""}${item}`;
|
|
378
|
-
let { content, pages } = item;
|
|
379
|
-
if (!content || pages && !pages.includes(page)) return s;
|
|
380
|
-
return `${s}${s ? "\n" : ""}${content}`;
|
|
381
|
-
}, "");
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
// src/bin/content/toFileContent.ts
|
|
385
|
-
function toFileContent(x) {
|
|
386
|
-
let s = x.replace(
|
|
387
|
-
/\s+(\r?\n *<\/?(script|link|head|body|html|meta|title)[> ])/g,
|
|
388
|
-
"$1"
|
|
389
|
-
).replace(
|
|
390
|
-
/\s+(\r?\n *<\/?(main|header|footer|nav|section|div|h\d|p|ul|ol|li|table)[> ])/g,
|
|
391
|
-
"$1"
|
|
392
|
-
).trim();
|
|
393
|
-
return `${s}
|
|
394
|
-
`;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
// src/bin/content/getRedirectContent.ts
|
|
398
|
-
function getRedirectContent(ctx) {
|
|
399
|
-
let { redirect } = ctx;
|
|
400
|
-
let escapedRedirect = escapeHTML(redirect);
|
|
401
|
-
return toFileContent(`
|
|
402
|
-
<!DOCTYPE html>
|
|
403
|
-
<html lang="en" data-layout="redirect" class="blank">
|
|
404
|
-
<head>
|
|
405
|
-
${getInjectedContent(ctx, "redirect", "head", "prepend")}
|
|
406
|
-
<meta charset="utf-8">
|
|
407
|
-
<meta name="viewport" content="width=device-width">
|
|
408
|
-
<meta http-equiv="refresh" content="0; URL=${escapedRedirect}">
|
|
409
|
-
${getIconTag(ctx)}
|
|
410
|
-
${getInjectedContent(ctx, "redirect", "head", "append")}
|
|
411
|
-
</head>
|
|
412
|
-
<body>
|
|
413
|
-
${getInjectedContent(ctx, "redirect", "body", "prepend")}
|
|
414
|
-
${getCounterContent(ctx)}
|
|
415
|
-
${getInjectedContent(ctx, "redirect", "body", "append")}
|
|
416
|
-
<script>window.location.replace("${escapedRedirect}");</script>
|
|
417
|
-
</body>
|
|
418
|
-
</html>
|
|
419
|
-
`);
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
// src/utils/escapeRegExp.ts
|
|
423
|
-
function escapeRegExp(s) {
|
|
424
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
425
|
-
}
|
|
426
|
-
|
|
427
328
|
// src/bin/getRepoLink.ts
|
|
428
329
|
function getRepoLink({ repo }, className) {
|
|
429
330
|
if (!repo) return "";
|
|
@@ -431,6 +332,22 @@ function getRepoLink({ repo }, className) {
|
|
|
431
332
|
return `<a href="${repo}"${className ? ` class="${className}"` : ""} target="_blank">${caption}</a>`;
|
|
432
333
|
}
|
|
433
334
|
|
|
335
|
+
// src/bin/getRepoMetadata.ts
|
|
336
|
+
async function getRepoMetadata({
|
|
337
|
+
repo
|
|
338
|
+
}) {
|
|
339
|
+
if (repo?.startsWith("https://github.com/")) {
|
|
340
|
+
try {
|
|
341
|
+
let repoMetadata = await fetchContent(
|
|
342
|
+
repo.replace("https://github.com/", "https://api.github.com/repos/")
|
|
343
|
+
);
|
|
344
|
+
return JSON.parse(repoMetadata);
|
|
345
|
+
} catch {
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return {};
|
|
349
|
+
}
|
|
350
|
+
|
|
434
351
|
// src/bin/parsing/getParsedContent.ts
|
|
435
352
|
import { JSDOM as JSDOM2 } from "jsdom";
|
|
436
353
|
import Markdown from "markdown-it";
|
|
@@ -652,6 +569,22 @@ async function getParsedContent(ctx) {
|
|
|
652
569
|
return parsedContent;
|
|
653
570
|
}
|
|
654
571
|
|
|
572
|
+
// src/bin/content/getCounterContent.ts
|
|
573
|
+
function getCounterContent({ ymid }) {
|
|
574
|
+
if (!ymid) return "";
|
|
575
|
+
return `
|
|
576
|
+
<script>
|
|
577
|
+
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
|
578
|
+
m[i].l=1*new Date();
|
|
579
|
+
for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
|
|
580
|
+
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
|
581
|
+
(window, document, "script", "https://mc.yandex.com/metrika/tag.js", "ym");
|
|
582
|
+
ym(${ymid}, "init", {clickmap: true, trackLinks: true, accurateTrackBounce: true});
|
|
583
|
+
</script>
|
|
584
|
+
<noscript><div><img src="https://mc.yandex.com/watch/${ymid}" style="position:absolute;left:-9999px;" alt=""></div></noscript>
|
|
585
|
+
`.trim();
|
|
586
|
+
}
|
|
587
|
+
|
|
655
588
|
// src/bin/content/getCSSRoot.ts
|
|
656
589
|
import { exec as defaultExec } from "node:child_process";
|
|
657
590
|
import { cp } from "node:fs/promises";
|
|
@@ -709,13 +642,44 @@ function getDefaultCodeStyleContent(cssRoot) {
|
|
|
709
642
|
`.trim();
|
|
710
643
|
}
|
|
711
644
|
|
|
712
|
-
// src/bin/content/
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
645
|
+
// src/bin/content/getIcon.ts
|
|
646
|
+
var iconTypeMap = {
|
|
647
|
+
ico: "image/x-icon",
|
|
648
|
+
svg: "image/svg+xml",
|
|
649
|
+
png: "image/png",
|
|
650
|
+
gif: "image/gif",
|
|
651
|
+
jpg: "image/jpeg",
|
|
652
|
+
jpeg: "image/jpeg"
|
|
653
|
+
};
|
|
654
|
+
function getIcon({ favicon, faviconType }) {
|
|
655
|
+
let icon = {
|
|
656
|
+
url: favicon,
|
|
657
|
+
type: faviconType
|
|
658
|
+
};
|
|
659
|
+
if (icon.url && !icon.type) {
|
|
660
|
+
let ext = icon.url.split("/").at(-1)?.split(".").at(-1)?.toLowerCase();
|
|
661
|
+
if (ext) icon.type = iconTypeMap[ext];
|
|
662
|
+
}
|
|
663
|
+
return icon;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
// src/bin/content/getIconTag.ts
|
|
667
|
+
function getIconTag(ctx) {
|
|
668
|
+
let { url, type } = getIcon(ctx);
|
|
669
|
+
return url ? `<link rel="icon"${type ? ` type="${type}"` : ""} href="${url}">` : "";
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// src/bin/content/getInjectedContent.ts
|
|
673
|
+
function getInjectedContent(ctx, page, target, mode) {
|
|
674
|
+
let injectedContent = ctx[mode]?.[target];
|
|
675
|
+
if (!injectedContent) return "";
|
|
676
|
+
return (Array.isArray(injectedContent) ? injectedContent : [injectedContent]).reduce((s, item) => {
|
|
677
|
+
if (item === void 0) return s;
|
|
678
|
+
if (typeof item === "string") return `${s}${s ? "\n" : ""}${item}`;
|
|
679
|
+
let { content, pages } = item;
|
|
680
|
+
if (!content || pages && !pages.includes(page)) return s;
|
|
681
|
+
return `${s}${s ? "\n" : ""}${content}`;
|
|
682
|
+
}, "");
|
|
719
683
|
}
|
|
720
684
|
|
|
721
685
|
// src/bin/content/getPlainTitle.ts
|
|
@@ -733,6 +697,119 @@ async function getMainTitle(ctx) {
|
|
|
733
697
|
return htmlTitle || parsedTitle || plainTitle;
|
|
734
698
|
}
|
|
735
699
|
|
|
700
|
+
// src/bin/content/toFileContent.ts
|
|
701
|
+
function toFileContent(x) {
|
|
702
|
+
let s = x.replace(
|
|
703
|
+
/\s+(\r?\n *<\/?(script|link|head|body|html|meta|title)[> ])/g,
|
|
704
|
+
"$1"
|
|
705
|
+
).replace(
|
|
706
|
+
/\s+(\r?\n *<\/?(main|header|footer|nav|section|div|h\d|p|ul|ol|li|table)[> ])/g,
|
|
707
|
+
"$1"
|
|
708
|
+
).trim();
|
|
709
|
+
return `${s}
|
|
710
|
+
`;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
// src/bin/content/tweakTypography.ts
|
|
714
|
+
function tweakTypography(s = "") {
|
|
715
|
+
return s.replace(/\b(for|in|on|at|to|with|a|an|the|its)\s+/gi, "$1\xA0").replace(/\b(React)\s+(apps?)\b/gi, "$1\xA0$2");
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
// src/bin/content/getIndexContent.ts
|
|
719
|
+
async function getIndexContent(ctx) {
|
|
720
|
+
let {
|
|
721
|
+
root,
|
|
722
|
+
contentDir = "",
|
|
723
|
+
description: packageDescription,
|
|
724
|
+
backstory
|
|
725
|
+
} = ctx;
|
|
726
|
+
let counterContent = getCounterContent(ctx);
|
|
727
|
+
let escapedPackageDescription = escapeHTML(packageDescription);
|
|
728
|
+
let repoDescription = (await getRepoMetadata(ctx)).description;
|
|
729
|
+
let { description, nav } = await getParsedContent(ctx);
|
|
730
|
+
let descriptionContent = escapeHTML(
|
|
731
|
+
tweakTypography(repoDescription || description)
|
|
732
|
+
);
|
|
733
|
+
let plainTitle = await getPlainTitle(ctx);
|
|
734
|
+
let cssRoot = await getCSSRoot(ctx, "index");
|
|
735
|
+
let links = [
|
|
736
|
+
`<a href="${root}${contentDir}" class="primary">Docs</a>`,
|
|
737
|
+
getRepoLink(ctx),
|
|
738
|
+
backstory ? `<a href="${backstory}">Backstory</a>` : ""
|
|
739
|
+
].filter((x) => x !== "");
|
|
740
|
+
let sep = ' <span class="sep">\xB7</span> ';
|
|
741
|
+
return toFileContent(`
|
|
742
|
+
<!DOCTYPE html>
|
|
743
|
+
<html lang="en" data-layout="index" class="aux">
|
|
744
|
+
<head>
|
|
745
|
+
${getInjectedContent(ctx, "index", "head", "prepend")}
|
|
746
|
+
<meta charset="utf-8">
|
|
747
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
748
|
+
<meta name="description" content="${plainTitle}${escapedPackageDescription ? `: ${escapedPackageDescription}` : ""}">
|
|
749
|
+
<title>${plainTitle}${escapedPackageDescription ? ` | ${escapedPackageDescription}` : ""}</title>
|
|
750
|
+
<link rel="stylesheet" href="${cssRoot}/base.css">
|
|
751
|
+
<link rel="stylesheet" href="${cssRoot}/index.css">
|
|
752
|
+
${getIconTag(ctx)}
|
|
753
|
+
<link rel="prefetch" href="${root}${contentDir}">
|
|
754
|
+
${nav[0] ? `<link rel="prefetch" href="${root}${contentDir}/${nav[0]?.id ?? ""}">` : ""}
|
|
755
|
+
${getInjectedContent(ctx, "index", "head", "append")}
|
|
756
|
+
</head>
|
|
757
|
+
<body>
|
|
758
|
+
${getInjectedContent(ctx, "index", "body", "prepend")}
|
|
759
|
+
<div class="layout">
|
|
760
|
+
<main>
|
|
761
|
+
<h1>${await getMainTitle(ctx)}</h1>
|
|
762
|
+
<p class="description">${descriptionContent}</p>
|
|
763
|
+
${links.length === 0 ? "" : `<p class="links">${links.join(sep)}</p>`}
|
|
764
|
+
</main>
|
|
765
|
+
</div>
|
|
766
|
+
${[descriptionContent].some((s) => s.includes("<pre><code ")) ? getInjectedContent(ctx, "index", ":has-code", "append") || getDefaultCodeStyleContent(cssRoot) : ""}
|
|
767
|
+
${counterContent}
|
|
768
|
+
${getInjectedContent(ctx, "index", "body", "append")}
|
|
769
|
+
</body>
|
|
770
|
+
</html>
|
|
771
|
+
`);
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// src/bin/content/getRedirectContent.ts
|
|
775
|
+
function getRedirectContent(ctx) {
|
|
776
|
+
let { redirect } = ctx;
|
|
777
|
+
let escapedRedirect = escapeHTML(redirect);
|
|
778
|
+
return toFileContent(`
|
|
779
|
+
<!DOCTYPE html>
|
|
780
|
+
<html lang="en" data-layout="redirect" class="blank">
|
|
781
|
+
<head>
|
|
782
|
+
${getInjectedContent(ctx, "redirect", "head", "prepend")}
|
|
783
|
+
<meta charset="utf-8">
|
|
784
|
+
<meta name="viewport" content="width=device-width">
|
|
785
|
+
<meta http-equiv="refresh" content="0; URL=${escapedRedirect}">
|
|
786
|
+
${getIconTag(ctx)}
|
|
787
|
+
${getInjectedContent(ctx, "redirect", "head", "append")}
|
|
788
|
+
</head>
|
|
789
|
+
<body>
|
|
790
|
+
${getInjectedContent(ctx, "redirect", "body", "prepend")}
|
|
791
|
+
${getCounterContent(ctx)}
|
|
792
|
+
${getInjectedContent(ctx, "redirect", "body", "append")}
|
|
793
|
+
<script>window.location.replace("${escapedRedirect}");</script>
|
|
794
|
+
</body>
|
|
795
|
+
</html>
|
|
796
|
+
`);
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
// src/utils/escapeRegExp.ts
|
|
800
|
+
function escapeRegExp(s) {
|
|
801
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
// src/bin/content/getInstallationContent.ts
|
|
805
|
+
async function getInstallationContent(ctx) {
|
|
806
|
+
let { name, isDevDep } = ctx;
|
|
807
|
+
let { installation } = await getParsedContent(ctx);
|
|
808
|
+
if (!installation || isDevDep !== void 0)
|
|
809
|
+
installation = `npm i${isDevDep ? " -D" : ""} ${name}`;
|
|
810
|
+
return `<code>${escapeHTML(installation)}</code>`;
|
|
811
|
+
}
|
|
812
|
+
|
|
736
813
|
// src/bin/content/getNav.ts
|
|
737
814
|
import { JSDOM as JSDOM3 } from "jsdom";
|
|
738
815
|
|
|
@@ -816,11 +893,6 @@ ${navContent}
|
|
|
816
893
|
</nav>`;
|
|
817
894
|
}
|
|
818
895
|
|
|
819
|
-
// src/bin/content/tweakTypography.ts
|
|
820
|
-
function tweakTypography(s = "") {
|
|
821
|
-
return s.replace(/\b(for|in|on|at|to|with|a|an|the|its)\s+/gi, "$1\xA0").replace(/\b(React)\s+(apps?)\b/gi, "$1\xA0$2");
|
|
822
|
-
}
|
|
823
|
-
|
|
824
896
|
// src/bin/content/getSectionContent.ts
|
|
825
897
|
async function getSectionContent(ctx, index) {
|
|
826
898
|
let { root, contentDir = "" } = ctx;
|
|
@@ -892,10 +964,11 @@ ${getInjectedContent(ctx, "section", "body", "append")}
|
|
|
892
964
|
}
|
|
893
965
|
|
|
894
966
|
// src/bin/content/getStartContent.ts
|
|
895
|
-
async function getStartContent(ctx, delay
|
|
967
|
+
async function getStartContent(ctx, delay) {
|
|
896
968
|
let { root, contentDir = "" } = ctx;
|
|
897
969
|
let { nav } = await getParsedContent(ctx);
|
|
898
970
|
let plainTitle = await getPlainTitle(ctx);
|
|
971
|
+
let jsRedirect = `window.location.replace("${root}${contentDir}/${nav[0]?.id}");`;
|
|
899
972
|
return toFileContent(`
|
|
900
973
|
<!DOCTYPE html>
|
|
901
974
|
<html lang="en" data-layout="start" class="blank">
|
|
@@ -903,11 +976,11 @@ async function getStartContent(ctx, delay = 0) {
|
|
|
903
976
|
${getInjectedContent(ctx, "start", "head", "prepend")}
|
|
904
977
|
<meta charset="utf-8">
|
|
905
978
|
<meta name="viewport" content="width=device-width">
|
|
906
|
-
<meta http-equiv="refresh" content="${delay}; URL=${root}${contentDir}/${nav[0]?.id}">
|
|
979
|
+
<meta http-equiv="refresh" content="${delay ?? 0}; URL=${root}${contentDir}/${nav[0]?.id}">
|
|
907
980
|
<title>${plainTitle}</title>
|
|
908
|
-
<link rel="stylesheet" href="${await getCSSRoot(ctx, "
|
|
981
|
+
<link rel="stylesheet" href="${await getCSSRoot(ctx, "content")}/base.css">
|
|
909
982
|
${getIconTag(ctx)}
|
|
910
|
-
<script
|
|
983
|
+
<script>${delay === void 0 ? jsRedirect : `setTimeout(() => { ${jsRedirect} }, ${delay * 1e3});`}</script>
|
|
911
984
|
${getInjectedContent(ctx, "start", "head", "append")}
|
|
912
985
|
</head>
|
|
913
986
|
<body>
|
|
@@ -939,9 +1012,8 @@ async function setContent(ctx) {
|
|
|
939
1012
|
await getSectionContent(ctx, i)
|
|
940
1013
|
)
|
|
941
1014
|
),
|
|
942
|
-
|
|
943
|
-
writeFile2(join5(dir, "index.html"), await getStartContent(ctx
|
|
944
|
-
writeFile2(join5(dir, "start.html"), await getStartContent(ctx))
|
|
1015
|
+
writeFile2(join5(dir, "index.html"), await getIndexContent(ctx)),
|
|
1016
|
+
writeFile2(join5(dir, contentDir, "index.html"), await getStartContent(ctx))
|
|
945
1017
|
]);
|
|
946
1018
|
}
|
|
947
1019
|
|
package/dist/css/index.css
CHANGED
|
@@ -1,254 +1,42 @@
|
|
|
1
1
|
:root {
|
|
2
|
-
|
|
3
|
-
}
|
|
4
|
-
body {
|
|
5
|
-
min-height: 100vh;
|
|
2
|
+
line-height: 1.35;
|
|
6
3
|
}
|
|
7
4
|
.layout {
|
|
8
5
|
display: flex;
|
|
6
|
+
min-height: 90vh;
|
|
9
7
|
flex-direction: column;
|
|
10
|
-
min-height: 95vh;
|
|
11
8
|
align-items: center;
|
|
12
9
|
justify-content: center;
|
|
13
|
-
|
|
14
|
-
@media (max-width: 840px) {
|
|
15
|
-
:root {
|
|
16
|
-
--content-padding-x: 1.75rem;
|
|
17
|
-
}
|
|
18
|
-
.layout {
|
|
19
|
-
min-height: 100vh;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
main {
|
|
24
|
-
display: flex;
|
|
25
|
-
width: 100%;
|
|
26
|
-
align-items: flex-start;
|
|
27
|
-
justify-content: center;
|
|
28
|
-
padding: 0;
|
|
29
|
-
margin: 0;
|
|
10
|
+
padding: var(--content-padding-y) var(--content-padding-x);
|
|
30
11
|
box-sizing: border-box;
|
|
31
12
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
min-height: 100vh;
|
|
35
|
-
flex-direction: column;
|
|
36
|
-
margin: 0;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
h1 {
|
|
41
|
-
max-width: 16rem;
|
|
42
|
-
font-size: 1.6em;
|
|
43
|
-
font-weight: 900;
|
|
44
|
-
margin: 1rem 0;
|
|
45
|
-
}
|
|
46
|
-
@media (max-width: 840px) {
|
|
47
|
-
h1 {
|
|
48
|
-
max-width: none;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
h1 > a,
|
|
52
|
-
h1 > a:link,
|
|
53
|
-
h1 > a:hover,
|
|
54
|
-
h1 > a:visited,
|
|
55
|
-
h1 > a:active {
|
|
56
|
-
border-bottom: none;
|
|
57
|
-
}
|
|
58
|
-
h1 sup {
|
|
59
|
-
font-size: 0.5em;
|
|
60
|
-
}
|
|
61
|
-
header {
|
|
62
|
-
display: block;
|
|
13
|
+
main {
|
|
14
|
+
width: 500px;
|
|
63
15
|
text-align: center;
|
|
64
|
-
padding: 0 var(--content-padding-x);
|
|
65
|
-
}
|
|
66
|
-
.description {
|
|
67
|
-
margin: 0;
|
|
68
|
-
}
|
|
69
|
-
.description p {
|
|
70
|
-
margin: 0;
|
|
71
|
-
}
|
|
72
|
-
.description p + p {
|
|
73
|
-
margin-top: 0.75em;
|
|
74
|
-
}
|
|
75
|
-
.description em {
|
|
76
|
-
font-style: normal;
|
|
77
|
-
}
|
|
78
|
-
.actions {
|
|
79
|
-
margin: 1.25rem 0;
|
|
80
|
-
}
|
|
81
|
-
.actions .sep {
|
|
82
|
-
display: block;
|
|
83
|
-
height: 0.01em;
|
|
84
|
-
font-size: 0;
|
|
85
|
-
overflow: hidden;
|
|
86
|
-
margin: 0.35rem 0;
|
|
87
|
-
}
|
|
88
|
-
.actions .primary {
|
|
89
|
-
font-weight: bold;
|
|
90
|
-
}
|
|
91
|
-
.ref {
|
|
92
|
-
font-size: 0.9em;
|
|
93
|
-
}
|
|
94
|
-
@media (max-width: 840px) {
|
|
95
|
-
.actions .sep {
|
|
96
|
-
margin: 0.5rem 0;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
section {
|
|
101
|
-
width: 50%;
|
|
102
|
-
min-height: 100vh;
|
|
103
|
-
align-self: stretch;
|
|
104
|
-
padding: 0;
|
|
105
16
|
box-sizing: border-box;
|
|
106
17
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
padding: 15vh 2.5em;
|
|
110
|
-
box-sizing: border-box;
|
|
111
|
-
}
|
|
112
|
-
section.intro-title {
|
|
113
|
-
display: flex;
|
|
114
|
-
width: 40%;
|
|
115
|
-
flex-direction: column;
|
|
116
|
-
align-items: flex-end;
|
|
117
|
-
text-align: right;
|
|
118
|
-
line-height: 1.3;
|
|
119
|
-
color: var(--emphatic-color);
|
|
120
|
-
background: linear-gradient(
|
|
121
|
-
to right,
|
|
122
|
-
var(--aux-background),
|
|
123
|
-
var(--aux-background-end)
|
|
124
|
-
);
|
|
125
|
-
border-right: 0.05em solid var(--aux-border-color);
|
|
126
|
-
}
|
|
127
|
-
section.intro-title .section-content {
|
|
128
|
-
display: flex;
|
|
129
|
-
flex-direction: column;
|
|
130
|
-
align-items: flex-end;
|
|
131
|
-
max-width: 24em;
|
|
132
|
-
}
|
|
133
|
-
section.intro-title:last-of-type {
|
|
134
|
-
width: 100%;
|
|
135
|
-
min-height: 100vh;
|
|
136
|
-
justify-content: center;
|
|
137
|
-
align-items: center;
|
|
138
|
-
text-align: center;
|
|
139
|
-
}
|
|
140
|
-
section.intro-title:last-of-type .section-content {
|
|
141
|
-
max-width: 36em;
|
|
142
|
-
align-items: center;
|
|
143
|
-
}
|
|
144
|
-
section.intro {
|
|
145
|
-
display: flex;
|
|
146
|
-
width: 60%;
|
|
147
|
-
flex-direction: column;
|
|
18
|
+
main .links {
|
|
19
|
+
font-size: 1.2em;
|
|
148
20
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
section.intro pre {
|
|
153
|
-
margin: 1.75em 0;
|
|
154
|
-
}
|
|
155
|
-
@media (max-width: 840px) {
|
|
156
|
-
section {
|
|
157
|
-
width: auto;
|
|
158
|
-
max-width: 100%;
|
|
159
|
-
min-height: auto;
|
|
160
|
-
}
|
|
161
|
-
section .section-content {
|
|
162
|
-
max-width: 100%;
|
|
163
|
-
padding: 1rem var(--content-padding-x);
|
|
164
|
-
}
|
|
165
|
-
section.intro-title {
|
|
166
|
-
flex: auto;
|
|
167
|
-
width: auto;
|
|
168
|
-
align-items: center;
|
|
169
|
-
justify-content: center;
|
|
170
|
-
text-align: center;
|
|
171
|
-
background: linear-gradient(
|
|
172
|
-
to bottom,
|
|
173
|
-
var(--aux-background),
|
|
174
|
-
var(--aux-background-end)
|
|
175
|
-
);
|
|
176
|
-
border-right: none;
|
|
177
|
-
border-bottom: 0.05em solid var(--aux-border-color);
|
|
178
|
-
}
|
|
179
|
-
section.intro-title .section-content {
|
|
180
|
-
min-height: 35vh;
|
|
181
|
-
align-items: center;
|
|
182
|
-
padding-top: 2rem;
|
|
183
|
-
padding-bottom: 2.5rem;
|
|
184
|
-
}
|
|
185
|
-
section.intro-title:last-child .section-content {
|
|
186
|
-
max-width: 100%;
|
|
187
|
-
padding-bottom: 2.5rem;
|
|
188
|
-
}
|
|
189
|
-
section.intro {
|
|
190
|
-
width: auto;
|
|
191
|
-
flex: none;
|
|
192
|
-
justify-content: flex-start;
|
|
193
|
-
align-items: center;
|
|
194
|
-
}
|
|
195
|
-
section.intro .section-content {
|
|
196
|
-
padding-top: 0.75rem;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
.features {
|
|
200
|
-
--list-padding-x: 1.25rem;
|
|
201
|
-
--list-item-padding-x: 0.35rem;
|
|
202
|
-
margin: 1em 0;
|
|
203
|
-
}
|
|
204
|
-
.features h2 {
|
|
205
|
-
font-size: 1.25em;
|
|
206
|
-
font-style: italic;
|
|
207
|
-
border: none;
|
|
208
|
-
padding: 0.1em calc(var(--list-padding-x) + var(--list-item-padding-x));
|
|
209
|
-
margin: 0.75em 0 0.5em;
|
|
21
|
+
main .links .sep {
|
|
22
|
+
display: inline-block;
|
|
23
|
+
margin: 0 0.15em;
|
|
210
24
|
}
|
|
211
|
-
.
|
|
212
|
-
|
|
213
|
-
padding: 0;
|
|
214
|
-
padding-inline-start: var(--list-padding-x);
|
|
215
|
-
margin: 0.5em 0 0;
|
|
25
|
+
main .links .primary {
|
|
26
|
+
font-weight: bold;
|
|
216
27
|
}
|
|
217
|
-
|
|
218
|
-
padding: 0.25em var(--list-item-padding-x);
|
|
28
|
+
main p {
|
|
219
29
|
margin: 0;
|
|
220
|
-
box-sizing: border-box;
|
|
221
|
-
}
|
|
222
|
-
.features > ul > li + li {
|
|
223
|
-
border-top: 0.075em solid var(--line-color);
|
|
224
|
-
}
|
|
225
|
-
@media (max-width: 840px) {
|
|
226
|
-
.features h2 {
|
|
227
|
-
text-align: center;
|
|
228
|
-
}
|
|
229
|
-
.features > ul > li {
|
|
230
|
-
width: 100%;
|
|
231
|
-
}
|
|
232
30
|
}
|
|
233
|
-
.
|
|
234
|
-
|
|
31
|
+
main p.description {
|
|
32
|
+
margin-top: 1rem;
|
|
235
33
|
}
|
|
236
|
-
.
|
|
237
|
-
margin:
|
|
34
|
+
main p.links {
|
|
35
|
+
margin-top: 1rem;
|
|
238
36
|
}
|
|
239
37
|
@media (max-width: 840px) {
|
|
240
|
-
|
|
241
|
-
|
|
38
|
+
main {
|
|
39
|
+
width: auto;
|
|
40
|
+
max-width: 500px;
|
|
242
41
|
}
|
|
243
42
|
}
|
|
244
|
-
p.installation {
|
|
245
|
-
margin: 0;
|
|
246
|
-
}
|
|
247
|
-
.installation code {
|
|
248
|
-
background: transparent;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
.li {
|
|
252
|
-
display: inline-block;
|
|
253
|
-
margin: 0.25em 0;
|
|
254
|
-
}
|
package/package.json
CHANGED
package/src/bin/cleanup.ts
CHANGED
|
@@ -2,10 +2,10 @@ import { rm } from "node:fs/promises";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import type { Context } from "../types/Context.ts";
|
|
4
4
|
|
|
5
|
-
export async function cleanup({ dir = "" }: Context) {
|
|
5
|
+
export async function cleanup({ dir = "", contentDir }: Context) {
|
|
6
6
|
await Promise.all(
|
|
7
|
-
[
|
|
8
|
-
return rm(join(dir, path), { force: true, recursive: true });
|
|
7
|
+
[contentDir, "index.html"].map((path) => {
|
|
8
|
+
return path && rm(join(dir, path), { force: true, recursive: true });
|
|
9
9
|
}),
|
|
10
10
|
);
|
|
11
11
|
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import type { Context } from "../../types/Context.ts";
|
|
2
2
|
import { escapeHTML } from "../../utils/escapeHTML.ts";
|
|
3
3
|
import { getRepoLink } from "../getRepoLink.ts";
|
|
4
|
+
import { getRepoMetadata } from "../getRepoMetadata.ts";
|
|
4
5
|
import { getParsedContent } from "../parsing/getParsedContent.ts";
|
|
5
6
|
import { getCounterContent } from "./getCounterContent.ts";
|
|
6
7
|
import { getCSSRoot } from "./getCSSRoot.ts";
|
|
7
8
|
import { getDefaultCodeStyleContent } from "./getDefaultCodeStyleContent.ts";
|
|
8
|
-
import { getDescriptionContent } from "./getDescriptionContent.ts";
|
|
9
9
|
import { getIconTag } from "./getIconTag.ts";
|
|
10
10
|
import { getInjectedContent } from "./getInjectedContent.ts";
|
|
11
|
-
import { getInstallationContent } from "./getInstallationContent.ts";
|
|
12
11
|
import { getMainTitle } from "./getMainTitle.ts";
|
|
13
12
|
import { getPlainTitle } from "./getPlainTitle.ts";
|
|
14
13
|
import { toFileContent } from "./toFileContent.ts";
|
|
14
|
+
import { tweakTypography } from "./tweakTypography.ts";
|
|
15
15
|
|
|
16
16
|
export async function getIndexContent(ctx: Context) {
|
|
17
17
|
let {
|
|
@@ -23,15 +23,27 @@ export async function getIndexContent(ctx: Context) {
|
|
|
23
23
|
|
|
24
24
|
let counterContent = getCounterContent(ctx);
|
|
25
25
|
let escapedPackageDescription = escapeHTML(packageDescription);
|
|
26
|
+
let repoDescription = (await getRepoMetadata(ctx)).description;
|
|
26
27
|
|
|
27
|
-
let { description,
|
|
28
|
+
let { description, nav } = await getParsedContent(ctx);
|
|
29
|
+
let descriptionContent = escapeHTML(
|
|
30
|
+
tweakTypography(repoDescription || description),
|
|
31
|
+
);
|
|
28
32
|
|
|
29
33
|
let plainTitle = await getPlainTitle(ctx);
|
|
30
34
|
let cssRoot = await getCSSRoot(ctx, "index");
|
|
31
35
|
|
|
36
|
+
let links = [
|
|
37
|
+
`<a href="${root}${contentDir}" class="primary">Docs</a>`,
|
|
38
|
+
getRepoLink(ctx),
|
|
39
|
+
backstory ? `<a href="${backstory}">Backstory</a>` : "",
|
|
40
|
+
].filter((x) => x !== "");
|
|
41
|
+
|
|
42
|
+
let sep = ' <span class="sep">·</span> ';
|
|
43
|
+
|
|
32
44
|
return toFileContent(`
|
|
33
45
|
<!DOCTYPE html>
|
|
34
|
-
<html lang="en" data-layout="index">
|
|
46
|
+
<html lang="en" data-layout="index" class="aux">
|
|
35
47
|
<head>
|
|
36
48
|
${getInjectedContent(ctx, "index", "head", "prepend")}
|
|
37
49
|
<meta charset="utf-8">
|
|
@@ -41,7 +53,7 @@ export async function getIndexContent(ctx: Context) {
|
|
|
41
53
|
<link rel="stylesheet" href="${cssRoot}/base.css">
|
|
42
54
|
<link rel="stylesheet" href="${cssRoot}/index.css">
|
|
43
55
|
${getIconTag(ctx)}
|
|
44
|
-
<link rel="prefetch" href="${root}
|
|
56
|
+
<link rel="prefetch" href="${root}${contentDir}">
|
|
45
57
|
${nav[0] ? `<link rel="prefetch" href="${root}${contentDir}/${nav[0]?.id ?? ""}">` : ""}
|
|
46
58
|
${getInjectedContent(ctx, "index", "head", "append")}
|
|
47
59
|
</head>
|
|
@@ -49,44 +61,13 @@ export async function getIndexContent(ctx: Context) {
|
|
|
49
61
|
${getInjectedContent(ctx, "index", "body", "prepend")}
|
|
50
62
|
<div class="layout">
|
|
51
63
|
<main>
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
<h1>${await getMainTitle(ctx)}</h1>
|
|
56
|
-
<div class="description">
|
|
57
|
-
${await getDescriptionContent(ctx)}
|
|
58
|
-
</div>
|
|
59
|
-
<p class="actions">
|
|
60
|
-
<a href="${root}start" class="primary">Docs</a>
|
|
61
|
-
<span class="sep"> • </span>
|
|
62
|
-
${getRepoLink(ctx)}
|
|
63
|
-
</p>
|
|
64
|
-
${backstory ? `<p class="ref"><a href="${backstory}">Backstory</a></p>` : ""}
|
|
65
|
-
<p class="installation">${await getInstallationContent(ctx)}</p>
|
|
66
|
-
${getInjectedContent(ctx, "index", "cover", "append")}
|
|
67
|
-
</div>
|
|
68
|
-
</section>
|
|
69
|
-
${
|
|
70
|
-
intro || features || note
|
|
71
|
-
? `
|
|
72
|
-
<section class="intro">
|
|
73
|
-
<div class="section-content">
|
|
74
|
-
${intro ? `<div class="intro">${intro}</div>` : ""}
|
|
75
|
-
${features ? `<div class="features">${features}</div>` : ""}
|
|
76
|
-
${note ? `<div class="note">${note}</div>` : ""}
|
|
77
|
-
<p class="pagenav">
|
|
78
|
-
<span class="next"><a href="${root}start">To the docs</a> <span class="icon">→</span></span>
|
|
79
|
-
</p>
|
|
80
|
-
</div>
|
|
81
|
-
</section>
|
|
82
|
-
`
|
|
83
|
-
: ""
|
|
84
|
-
}
|
|
64
|
+
<h1>${await getMainTitle(ctx)}</h1>
|
|
65
|
+
<p class="description">${descriptionContent}</p>
|
|
66
|
+
${links.length === 0 ? "" : `<p class="links">${links.join(sep)}</p>`}
|
|
85
67
|
</main>
|
|
86
68
|
</div>
|
|
87
|
-
|
|
88
69
|
${
|
|
89
|
-
[
|
|
70
|
+
[descriptionContent].some((s) => s.includes("<pre><code "))
|
|
90
71
|
? getInjectedContent(ctx, "index", ":has-code", "append") ||
|
|
91
72
|
getDefaultCodeStyleContent(cssRoot)
|
|
92
73
|
: ""
|
|
@@ -2,7 +2,6 @@ import type { Context } from "../../types/Context.ts";
|
|
|
2
2
|
import { escapeHTML } from "../../utils/escapeHTML.ts";
|
|
3
3
|
import { escapeRegExp } from "../../utils/escapeRegExp.ts";
|
|
4
4
|
import { getRepoLink } from "../getRepoLink.ts";
|
|
5
|
-
// import { getRepoMetadata } from "../getRepoMetadata.ts";
|
|
6
5
|
import { getParsedContent } from "../parsing/getParsedContent.ts";
|
|
7
6
|
import { stripHTML } from "../stripHTML.ts";
|
|
8
7
|
import { getCounterContent } from "./getCounterContent.ts";
|
|
@@ -19,8 +18,6 @@ import { tweakTypography } from "./tweakTypography.ts";
|
|
|
19
18
|
|
|
20
19
|
export async function getSectionContent(ctx: Context, index: number) {
|
|
21
20
|
let { root, contentDir = "" } = ctx;
|
|
22
|
-
// let repoDescription =
|
|
23
|
-
// index === 0 ? (await getRepoMetadata(ctx)).description : "";
|
|
24
21
|
let descriptionContent = escapeHTML(tweakTypography(ctx.description));
|
|
25
22
|
|
|
26
23
|
let cssRoot = await getCSSRoot(ctx, "content");
|
|
@@ -7,11 +7,13 @@ import { getInjectedContent } from "./getInjectedContent.ts";
|
|
|
7
7
|
import { getPlainTitle } from "./getPlainTitle.ts";
|
|
8
8
|
import { toFileContent } from "./toFileContent.ts";
|
|
9
9
|
|
|
10
|
-
export async function getStartContent(ctx: Context, delay
|
|
10
|
+
export async function getStartContent(ctx: Context, delay?: number) {
|
|
11
11
|
let { root, contentDir = "" } = ctx;
|
|
12
12
|
let { nav } = await getParsedContent(ctx);
|
|
13
13
|
let plainTitle = await getPlainTitle(ctx);
|
|
14
14
|
|
|
15
|
+
let jsRedirect = `window.location.replace("${root}${contentDir}/${nav[0]?.id}");`;
|
|
16
|
+
|
|
15
17
|
return toFileContent(`
|
|
16
18
|
<!DOCTYPE html>
|
|
17
19
|
<html lang="en" data-layout="start" class="blank">
|
|
@@ -19,11 +21,11 @@ export async function getStartContent(ctx: Context, delay = 0) {
|
|
|
19
21
|
${getInjectedContent(ctx, "start", "head", "prepend")}
|
|
20
22
|
<meta charset="utf-8">
|
|
21
23
|
<meta name="viewport" content="width=device-width">
|
|
22
|
-
<meta http-equiv="refresh" content="${delay}; URL=${root}${contentDir}/${nav[0]?.id}">
|
|
24
|
+
<meta http-equiv="refresh" content="${delay ?? 0}; URL=${root}${contentDir}/${nav[0]?.id}">
|
|
23
25
|
<title>${plainTitle}</title>
|
|
24
|
-
<link rel="stylesheet" href="${await getCSSRoot(ctx, "
|
|
26
|
+
<link rel="stylesheet" href="${await getCSSRoot(ctx, "content")}/base.css">
|
|
25
27
|
${getIconTag(ctx)}
|
|
26
|
-
<script
|
|
28
|
+
<script>${delay === undefined ? jsRedirect : `setTimeout(() => { ${jsRedirect} }, ${delay * 1000});`}</script>
|
|
27
29
|
${getInjectedContent(ctx, "start", "head", "append")}
|
|
28
30
|
</head>
|
|
29
31
|
<body>
|
package/src/bin/getConfig.ts
CHANGED
package/src/bin/setContent.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { writeFile } from "node:fs/promises";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import type { Context } from "../types/Context.ts";
|
|
4
4
|
import { createDirs } from "./content/createDirs.ts";
|
|
5
|
-
|
|
5
|
+
import { getIndexContent } from "./content/getIndexContent.ts";
|
|
6
6
|
import { getRedirectContent } from "./content/getRedirectContent.ts";
|
|
7
7
|
import { getSectionContent } from "./content/getSectionContent.ts";
|
|
8
8
|
import { getStartContent } from "./content/getStartContent.ts";
|
|
@@ -27,8 +27,7 @@ export async function setContent(ctx: Context) {
|
|
|
27
27
|
await getSectionContent(ctx, i),
|
|
28
28
|
),
|
|
29
29
|
),
|
|
30
|
-
|
|
31
|
-
writeFile(join(dir, "index.html"), await getStartContent(ctx
|
|
32
|
-
writeFile(join(dir, "start.html"), await getStartContent(ctx)),
|
|
30
|
+
writeFile(join(dir, "index.html"), await getIndexContent(ctx)),
|
|
31
|
+
writeFile(join(dir, contentDir, "index.html"), await getStartContent(ctx)),
|
|
33
32
|
]);
|
|
34
33
|
}
|
package/src/css/index.css
CHANGED
|
@@ -1,254 +1,42 @@
|
|
|
1
1
|
:root {
|
|
2
|
-
|
|
3
|
-
}
|
|
4
|
-
body {
|
|
5
|
-
min-height: 100vh;
|
|
2
|
+
line-height: 1.35;
|
|
6
3
|
}
|
|
7
4
|
.layout {
|
|
8
5
|
display: flex;
|
|
6
|
+
min-height: 90vh;
|
|
9
7
|
flex-direction: column;
|
|
10
|
-
min-height: 95vh;
|
|
11
8
|
align-items: center;
|
|
12
9
|
justify-content: center;
|
|
13
|
-
|
|
14
|
-
@media (max-width: 840px) {
|
|
15
|
-
:root {
|
|
16
|
-
--content-padding-x: 1.75rem;
|
|
17
|
-
}
|
|
18
|
-
.layout {
|
|
19
|
-
min-height: 100vh;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
main {
|
|
24
|
-
display: flex;
|
|
25
|
-
width: 100%;
|
|
26
|
-
align-items: flex-start;
|
|
27
|
-
justify-content: center;
|
|
28
|
-
padding: 0;
|
|
29
|
-
margin: 0;
|
|
10
|
+
padding: var(--content-padding-y) var(--content-padding-x);
|
|
30
11
|
box-sizing: border-box;
|
|
31
12
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
min-height: 100vh;
|
|
35
|
-
flex-direction: column;
|
|
36
|
-
margin: 0;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
h1 {
|
|
41
|
-
max-width: 16rem;
|
|
42
|
-
font-size: 1.6em;
|
|
43
|
-
font-weight: 900;
|
|
44
|
-
margin: 1rem 0;
|
|
45
|
-
}
|
|
46
|
-
@media (max-width: 840px) {
|
|
47
|
-
h1 {
|
|
48
|
-
max-width: none;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
h1 > a,
|
|
52
|
-
h1 > a:link,
|
|
53
|
-
h1 > a:hover,
|
|
54
|
-
h1 > a:visited,
|
|
55
|
-
h1 > a:active {
|
|
56
|
-
border-bottom: none;
|
|
57
|
-
}
|
|
58
|
-
h1 sup {
|
|
59
|
-
font-size: 0.5em;
|
|
60
|
-
}
|
|
61
|
-
header {
|
|
62
|
-
display: block;
|
|
13
|
+
main {
|
|
14
|
+
width: 500px;
|
|
63
15
|
text-align: center;
|
|
64
|
-
padding: 0 var(--content-padding-x);
|
|
65
|
-
}
|
|
66
|
-
.description {
|
|
67
|
-
margin: 0;
|
|
68
|
-
}
|
|
69
|
-
.description p {
|
|
70
|
-
margin: 0;
|
|
71
|
-
}
|
|
72
|
-
.description p + p {
|
|
73
|
-
margin-top: 0.75em;
|
|
74
|
-
}
|
|
75
|
-
.description em {
|
|
76
|
-
font-style: normal;
|
|
77
|
-
}
|
|
78
|
-
.actions {
|
|
79
|
-
margin: 1.25rem 0;
|
|
80
|
-
}
|
|
81
|
-
.actions .sep {
|
|
82
|
-
display: block;
|
|
83
|
-
height: 0.01em;
|
|
84
|
-
font-size: 0;
|
|
85
|
-
overflow: hidden;
|
|
86
|
-
margin: 0.35rem 0;
|
|
87
|
-
}
|
|
88
|
-
.actions .primary {
|
|
89
|
-
font-weight: bold;
|
|
90
|
-
}
|
|
91
|
-
.ref {
|
|
92
|
-
font-size: 0.9em;
|
|
93
|
-
}
|
|
94
|
-
@media (max-width: 840px) {
|
|
95
|
-
.actions .sep {
|
|
96
|
-
margin: 0.5rem 0;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
section {
|
|
101
|
-
width: 50%;
|
|
102
|
-
min-height: 100vh;
|
|
103
|
-
align-self: stretch;
|
|
104
|
-
padding: 0;
|
|
105
16
|
box-sizing: border-box;
|
|
106
17
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
padding: 15vh 2.5em;
|
|
110
|
-
box-sizing: border-box;
|
|
111
|
-
}
|
|
112
|
-
section.intro-title {
|
|
113
|
-
display: flex;
|
|
114
|
-
width: 40%;
|
|
115
|
-
flex-direction: column;
|
|
116
|
-
align-items: flex-end;
|
|
117
|
-
text-align: right;
|
|
118
|
-
line-height: 1.3;
|
|
119
|
-
color: var(--emphatic-color);
|
|
120
|
-
background: linear-gradient(
|
|
121
|
-
to right,
|
|
122
|
-
var(--aux-background),
|
|
123
|
-
var(--aux-background-end)
|
|
124
|
-
);
|
|
125
|
-
border-right: 0.05em solid var(--aux-border-color);
|
|
126
|
-
}
|
|
127
|
-
section.intro-title .section-content {
|
|
128
|
-
display: flex;
|
|
129
|
-
flex-direction: column;
|
|
130
|
-
align-items: flex-end;
|
|
131
|
-
max-width: 24em;
|
|
132
|
-
}
|
|
133
|
-
section.intro-title:last-of-type {
|
|
134
|
-
width: 100%;
|
|
135
|
-
min-height: 100vh;
|
|
136
|
-
justify-content: center;
|
|
137
|
-
align-items: center;
|
|
138
|
-
text-align: center;
|
|
139
|
-
}
|
|
140
|
-
section.intro-title:last-of-type .section-content {
|
|
141
|
-
max-width: 36em;
|
|
142
|
-
align-items: center;
|
|
143
|
-
}
|
|
144
|
-
section.intro {
|
|
145
|
-
display: flex;
|
|
146
|
-
width: 60%;
|
|
147
|
-
flex-direction: column;
|
|
18
|
+
main .links {
|
|
19
|
+
font-size: 1.2em;
|
|
148
20
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
section.intro pre {
|
|
153
|
-
margin: 1.75em 0;
|
|
154
|
-
}
|
|
155
|
-
@media (max-width: 840px) {
|
|
156
|
-
section {
|
|
157
|
-
width: auto;
|
|
158
|
-
max-width: 100%;
|
|
159
|
-
min-height: auto;
|
|
160
|
-
}
|
|
161
|
-
section .section-content {
|
|
162
|
-
max-width: 100%;
|
|
163
|
-
padding: 1rem var(--content-padding-x);
|
|
164
|
-
}
|
|
165
|
-
section.intro-title {
|
|
166
|
-
flex: auto;
|
|
167
|
-
width: auto;
|
|
168
|
-
align-items: center;
|
|
169
|
-
justify-content: center;
|
|
170
|
-
text-align: center;
|
|
171
|
-
background: linear-gradient(
|
|
172
|
-
to bottom,
|
|
173
|
-
var(--aux-background),
|
|
174
|
-
var(--aux-background-end)
|
|
175
|
-
);
|
|
176
|
-
border-right: none;
|
|
177
|
-
border-bottom: 0.05em solid var(--aux-border-color);
|
|
178
|
-
}
|
|
179
|
-
section.intro-title .section-content {
|
|
180
|
-
min-height: 35vh;
|
|
181
|
-
align-items: center;
|
|
182
|
-
padding-top: 2rem;
|
|
183
|
-
padding-bottom: 2.5rem;
|
|
184
|
-
}
|
|
185
|
-
section.intro-title:last-child .section-content {
|
|
186
|
-
max-width: 100%;
|
|
187
|
-
padding-bottom: 2.5rem;
|
|
188
|
-
}
|
|
189
|
-
section.intro {
|
|
190
|
-
width: auto;
|
|
191
|
-
flex: none;
|
|
192
|
-
justify-content: flex-start;
|
|
193
|
-
align-items: center;
|
|
194
|
-
}
|
|
195
|
-
section.intro .section-content {
|
|
196
|
-
padding-top: 0.75rem;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
.features {
|
|
200
|
-
--list-padding-x: 1.25rem;
|
|
201
|
-
--list-item-padding-x: 0.35rem;
|
|
202
|
-
margin: 1em 0;
|
|
203
|
-
}
|
|
204
|
-
.features h2 {
|
|
205
|
-
font-size: 1.25em;
|
|
206
|
-
font-style: italic;
|
|
207
|
-
border: none;
|
|
208
|
-
padding: 0.1em calc(var(--list-padding-x) + var(--list-item-padding-x));
|
|
209
|
-
margin: 0.75em 0 0.5em;
|
|
21
|
+
main .links .sep {
|
|
22
|
+
display: inline-block;
|
|
23
|
+
margin: 0 0.15em;
|
|
210
24
|
}
|
|
211
|
-
.
|
|
212
|
-
|
|
213
|
-
padding: 0;
|
|
214
|
-
padding-inline-start: var(--list-padding-x);
|
|
215
|
-
margin: 0.5em 0 0;
|
|
25
|
+
main .links .primary {
|
|
26
|
+
font-weight: bold;
|
|
216
27
|
}
|
|
217
|
-
|
|
218
|
-
padding: 0.25em var(--list-item-padding-x);
|
|
28
|
+
main p {
|
|
219
29
|
margin: 0;
|
|
220
|
-
box-sizing: border-box;
|
|
221
|
-
}
|
|
222
|
-
.features > ul > li + li {
|
|
223
|
-
border-top: 0.075em solid var(--line-color);
|
|
224
|
-
}
|
|
225
|
-
@media (max-width: 840px) {
|
|
226
|
-
.features h2 {
|
|
227
|
-
text-align: center;
|
|
228
|
-
}
|
|
229
|
-
.features > ul > li {
|
|
230
|
-
width: 100%;
|
|
231
|
-
}
|
|
232
30
|
}
|
|
233
|
-
.
|
|
234
|
-
|
|
31
|
+
main p.description {
|
|
32
|
+
margin-top: 1rem;
|
|
235
33
|
}
|
|
236
|
-
.
|
|
237
|
-
margin:
|
|
34
|
+
main p.links {
|
|
35
|
+
margin-top: 1rem;
|
|
238
36
|
}
|
|
239
37
|
@media (max-width: 840px) {
|
|
240
|
-
|
|
241
|
-
|
|
38
|
+
main {
|
|
39
|
+
width: auto;
|
|
40
|
+
max-width: 500px;
|
|
242
41
|
}
|
|
243
42
|
}
|
|
244
|
-
p.installation {
|
|
245
|
-
margin: 0;
|
|
246
|
-
}
|
|
247
|
-
.installation code {
|
|
248
|
-
background: transparent;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
.li {
|
|
252
|
-
display: inline-block;
|
|
253
|
-
margin: 0.25em 0;
|
|
254
|
-
}
|