@beforesemicolon/builder 1.8.1 → 1.8.11
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/cjs/docs/markdown-layout/index.js +1 -0
- package/dist/cjs/docs/markdown-layout/marked-extension.js +1 -0
- package/dist/cjs/docs/markdown-layout/parser.js +7 -0
- package/dist/cjs/docs/markdown-layout/renderer.js +1 -0
- package/dist/cjs/docs/markdown-layout/types.js +1 -0
- package/dist/cjs/docs/run.js +76 -1
- package/dist/cjs/docs/templates/fading-citrus/layouts/_code-snippet.js +53 -0
- package/dist/cjs/docs/templates/fading-citrus/layouts/_layout-utils.js +89 -0
- package/dist/cjs/docs/templates/fading-citrus/layouts/document.js +6 -3
- package/dist/cjs/docs/templates/fading-citrus/layouts/landing-cta.js +30 -0
- package/dist/cjs/docs/templates/fading-citrus/layouts/landing-ecosystem.js +43 -0
- package/dist/cjs/docs/templates/fading-citrus/layouts/landing-features.js +25 -0
- package/dist/cjs/docs/templates/fading-citrus/layouts/landing-hero.js +81 -0
- package/dist/cjs/docs/templates/fading-citrus/layouts/landing-install.js +116 -0
- package/dist/cjs/docs/templates/fading-citrus/layouts/landing-showcase.js +125 -0
- package/dist/cjs/docs/templates/fading-citrus/layouts/landing.js +7 -617
- package/dist/cjs/docs/templates/fading-citrus/template.config.js +100 -1
- package/dist/cjs/docs/types.js +1 -1
- package/dist/esm/docs/markdown-layout/index.js +1 -0
- package/dist/esm/docs/markdown-layout/marked-extension.js +1 -0
- package/dist/esm/docs/markdown-layout/parser.js +7 -0
- package/dist/esm/docs/markdown-layout/renderer.js +1 -0
- package/dist/esm/docs/markdown-layout/types.js +0 -0
- package/dist/esm/docs/run.js +76 -1
- package/dist/esm/docs/templates/fading-citrus/layouts/_code-snippet.js +53 -0
- package/dist/esm/docs/templates/fading-citrus/layouts/_layout-utils.js +89 -0
- package/dist/esm/docs/templates/fading-citrus/layouts/document.js +6 -3
- package/dist/esm/docs/templates/fading-citrus/layouts/landing-cta.js +30 -0
- package/dist/esm/docs/templates/fading-citrus/layouts/landing-ecosystem.js +43 -0
- package/dist/esm/docs/templates/fading-citrus/layouts/landing-features.js +25 -0
- package/dist/esm/docs/templates/fading-citrus/layouts/landing-hero.js +81 -0
- package/dist/esm/docs/templates/fading-citrus/layouts/landing-install.js +116 -0
- package/dist/esm/docs/templates/fading-citrus/layouts/landing-showcase.js +125 -0
- package/dist/esm/docs/templates/fading-citrus/layouts/landing.js +7 -617
- package/dist/esm/docs/templates/fading-citrus/template.config.js +100 -1
- package/dist/types/docs/markdown-layout/index.d.ts +4 -0
- package/dist/types/docs/markdown-layout/marked-extension.d.ts +8 -0
- package/dist/types/docs/markdown-layout/parser.d.ts +12 -0
- package/dist/types/docs/markdown-layout/renderer.d.ts +3 -0
- package/dist/types/docs/markdown-layout/types.d.ts +35 -0
- package/dist/types/docs/run.d.ts +12 -1
- package/dist/types/docs/types.d.ts +22 -0
- package/package.json +3 -2
- package/dist/cjs/docs/templates/fading-citrus/layouts/_copy-code.js +0 -50
- package/dist/esm/docs/templates/fading-citrus/layouts/_copy-code.js +0 -50
|
@@ -1,6 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
renderCodeBlock,
|
|
3
|
+
renderCodeCopyScript,
|
|
4
|
+
} from './layouts/_code-snippet.js'
|
|
5
|
+
import landingHero from './layouts/landing-hero.js'
|
|
6
|
+
import landingEcosystem from './layouts/landing-ecosystem.js'
|
|
7
|
+
import landingFeatures from './layouts/landing-features.js'
|
|
8
|
+
import landingShowcase, {
|
|
9
|
+
renderShowcaseScript,
|
|
10
|
+
} from './layouts/landing-showcase.js'
|
|
11
|
+
import landingInstall, {
|
|
12
|
+
renderInstallScript,
|
|
13
|
+
} from './layouts/landing-install.js'
|
|
14
|
+
import landingCta from './layouts/landing-cta.js'
|
|
2
15
|
|
|
3
16
|
export default {
|
|
17
|
+
markdownLayouts: {
|
|
18
|
+
'landing-hero': landingHero,
|
|
19
|
+
'landing-ecosystem': landingEcosystem,
|
|
20
|
+
'landing-features': landingFeatures,
|
|
21
|
+
'landing-showcase': landingShowcase,
|
|
22
|
+
'landing-install': landingInstall,
|
|
23
|
+
'landing-cta': landingCta,
|
|
24
|
+
},
|
|
4
25
|
markedOptions: {
|
|
5
26
|
renderer: {
|
|
6
27
|
code({ lang, raw }) {
|
|
@@ -11,4 +32,82 @@ export default {
|
|
|
11
32
|
},
|
|
12
33
|
},
|
|
13
34
|
},
|
|
35
|
+
scripts: {
|
|
36
|
+
'code-copy': {
|
|
37
|
+
match: 'code-copy-btn',
|
|
38
|
+
render: renderCodeCopyScript,
|
|
39
|
+
},
|
|
40
|
+
showcase: {
|
|
41
|
+
match: 'data-fading-citrus-showcase',
|
|
42
|
+
render: renderShowcaseScript,
|
|
43
|
+
},
|
|
44
|
+
install: {
|
|
45
|
+
match: 'data-fading-citrus-install',
|
|
46
|
+
render: renderInstallScript,
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
theme: {
|
|
50
|
+
light: {
|
|
51
|
+
'--background': 'oklch(0.98 0.006 250)',
|
|
52
|
+
'--foreground': 'oklch(0.18 0.015 250)',
|
|
53
|
+
'--card': 'oklch(1 0 0)',
|
|
54
|
+
'--primary': 'oklch(0.66 0.18 45)',
|
|
55
|
+
'--primary-glow': 'oklch(0.72 0.19 50)',
|
|
56
|
+
'--primary-foreground': 'oklch(0.98 0.006 250)',
|
|
57
|
+
'--secondary': 'oklch(0.93 0.01 250)',
|
|
58
|
+
'--muted': 'oklch(0.94 0.01 250)',
|
|
59
|
+
'--muted-foreground': 'oklch(0.42 0.02 250)',
|
|
60
|
+
'--accent': 'oklch(0.58 0.16 200)',
|
|
61
|
+
'--border': 'oklch(0.86 0.018 250)',
|
|
62
|
+
'--ring': 'oklch(0.66 0.18 45)',
|
|
63
|
+
'--code-bg': 'oklch(0.16 0.015 250)',
|
|
64
|
+
'--syntax-comment': 'oklch(0.55 0.02 250)',
|
|
65
|
+
'--syntax-keyword': 'oklch(0.78 0.19 50)',
|
|
66
|
+
'--syntax-string': 'oklch(0.78 0.15 145)',
|
|
67
|
+
'--syntax-tag': 'oklch(0.72 0.16 200)',
|
|
68
|
+
'--syntax-attr': 'oklch(0.82 0.14 90)',
|
|
69
|
+
'--gradient-hero':
|
|
70
|
+
'radial-gradient(ellipse at top, oklch(0.86 0.08 45 / 0.35), transparent 60%)',
|
|
71
|
+
'--gradient-primary':
|
|
72
|
+
'linear-gradient(135deg, var(--primary), var(--primary-glow))',
|
|
73
|
+
'--gradient-text':
|
|
74
|
+
'linear-gradient(135deg, oklch(0.18 0.015 250), oklch(0.35 0.03 250))',
|
|
75
|
+
'--gradient-border':
|
|
76
|
+
'linear-gradient(135deg, oklch(0.66 0.18 45 / 0.45), oklch(0.58 0.16 200 / 0.25))',
|
|
77
|
+
'--shadow-glow': '0 0 60px -15px oklch(0.66 0.18 45 / 0.35)',
|
|
78
|
+
'--shadow-card':
|
|
79
|
+
'0 1px 0 0 oklch(1 0 0 / 0.75) inset, 0 20px 40px -20px oklch(0.18 0.015 250 / 0.18)',
|
|
80
|
+
},
|
|
81
|
+
dark: {
|
|
82
|
+
'--background': 'oklch(0.18 0.015 250)',
|
|
83
|
+
'--foreground': 'oklch(0.96 0.005 250)',
|
|
84
|
+
'--card': 'oklch(0.22 0.018 250)',
|
|
85
|
+
'--primary': 'oklch(0.74 0.18 45)',
|
|
86
|
+
'--primary-glow': 'oklch(0.78 0.19 50)',
|
|
87
|
+
'--primary-foreground': 'oklch(0.18 0.02 250)',
|
|
88
|
+
'--secondary': 'oklch(0.27 0.02 250)',
|
|
89
|
+
'--muted': 'oklch(0.25 0.018 250)',
|
|
90
|
+
'--muted-foreground': 'oklch(0.68 0.02 250)',
|
|
91
|
+
'--accent': 'oklch(0.7 0.16 200)',
|
|
92
|
+
'--border': 'oklch(0.3 0.02 250)',
|
|
93
|
+
'--ring': 'oklch(0.74 0.18 45)',
|
|
94
|
+
'--code-bg': 'oklch(0.16 0.015 250)',
|
|
95
|
+
'--syntax-comment': 'oklch(0.55 0.02 250)',
|
|
96
|
+
'--syntax-keyword': 'oklch(0.78 0.19 50)',
|
|
97
|
+
'--syntax-string': 'oklch(0.78 0.15 145)',
|
|
98
|
+
'--syntax-tag': 'oklch(0.72 0.16 200)',
|
|
99
|
+
'--syntax-attr': 'oklch(0.82 0.14 90)',
|
|
100
|
+
'--gradient-hero':
|
|
101
|
+
'radial-gradient(ellipse at top, oklch(0.28 0.08 45 / 0.35), transparent 60%)',
|
|
102
|
+
'--gradient-primary':
|
|
103
|
+
'linear-gradient(135deg, var(--primary), var(--primary-glow))',
|
|
104
|
+
'--gradient-text':
|
|
105
|
+
'linear-gradient(135deg, oklch(0.98 0.005 250), oklch(0.78 0.05 250))',
|
|
106
|
+
'--gradient-border':
|
|
107
|
+
'linear-gradient(135deg, oklch(0.74 0.18 45 / 0.5), oklch(0.7 0.16 200 / 0.3))',
|
|
108
|
+
'--shadow-glow': '0 0 60px -15px oklch(0.74 0.18 45 / 0.5)',
|
|
109
|
+
'--shadow-card':
|
|
110
|
+
'0 1px 0 0 oklch(1 0 0 / 0.05) inset, 0 20px 40px -20px oklch(0 0 0 / 0.5)',
|
|
111
|
+
},
|
|
112
|
+
},
|
|
14
113
|
}
|
package/dist/cjs/docs/types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var i=Object.defineProperty;var o=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var g=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of a(t))!p.call(e,r)&&r!==s&&i(e,r,{get:()=>t[r],enumerable:!(n=o(t,r))||n.enumerable});return e};var c=e=>g(i({},"__esModule",{value:!0}),e);var m={};module.exports=c(m);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./marked-extension.js";export*from"./parser.js";export*from"./renderer.js";export*from"./types.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var s=Object.defineProperty;var u=(t,e)=>s(t,"name",{value:e,configurable:!0});import{parseLayoutBlock as i,readLayoutBlock as y}from"./parser.js";import{renderDefaultMarkdownLayout as M,renderMarkdownLayout as w}from"./renderer.js";const N=u(({marked:t,handlers:e={},renderMarkdown:d})=>({extensions:[{name:"markdownLayout",level:"block",start(o){return o.match(/^::: layout /m)?.index},tokenizer(o){const n=y(o);if(n)return{...i(n),type:"markdownLayout",raw:n}},renderer(o){const n=o,a={marked:t,renderMarkdown(r){return d?d(r):t.parse(r)},renderDefault(r){return M(r,a)},renderParts(r){return r.items.map(k=>({...k,html:a.renderMarkdown(k.body)}))}};return w(n,a,e)}}]}),"createMarkdownLayoutExtension");export{N as createMarkdownLayoutExtension};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
var m=Object.defineProperty;var i=(n,t)=>m(n,"name",{value:t,configurable:!0});const a=/^::: layout(?:\s+.*)?$/,l=/^:::\s*$/,y=/^===(?:\s+.*)?$/,f=i(n=>{const t=n.replace(/^(['"])(.*)\1$/,"$2");return/^-?\d+(\.\d+)?$/.test(t)?Number(t):t==="true"?!0:t==="false"?!1:t},"coerceOptionValue"),c=i((n="")=>{const t=[],e=/\S+=("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|\S*)|"[^"]*"|'[^']*'|\S+/g;let r;for(;r=e.exec(n);)t.push(r[0]);return t},"tokenizeOptions"),d=i((n="")=>c(n).reduce((t,e)=>{const r=e.indexOf("=");if(r===-1)return t[e]=!0,t;const o=e.slice(0,r).trim(),s=e.slice(r+1).trim();return o&&(t[o]=f(s)),t},{}),"parseOptions"),h=i(n=>{const t=n.replace(/^:::\s*layout\s*/,"").trim(),[e="",...r]=c(t);if(!e)throw new Error(`Invalid layout header: ${n}`);return{layoutType:e,options:d(r.join(" "))}},"parseLayoutHeader"),w=i(n=>{const t=n.replace(/^===\s*/,"").trim();if(!t)return{name:null,options:{}};const[e=null,...r]=c(t);return{name:e,options:d(r.join(" "))}},"parseItemHeader"),L=i(n=>{const t=n.split(`
|
|
2
|
+
`),e=[];let r=0,o=null,s=[];const p=i(()=>{o&&(e.push({...o,body:s.join(`
|
|
3
|
+
`).trim()}),s=[])},"pushCurrent");for(const u of t){if(a.test(u.trim())){o&&s.push(u),r+=1;continue}if(l.test(u.trim())&&r>0){r-=1,o&&s.push(u);continue}if(r===0&&y.test(u.trim())){p(),o=w(u.trim());continue}o&&s.push(u)}return p(),e.length?e:[{name:null,options:{},body:n.trim()}]},"splitLayoutItems"),$=i(n=>{const t=n.replace(/\s+$/,"").split(`
|
|
4
|
+
`),e=t.shift();if(!e||!a.test(e.trim()))throw new Error("Layout block must start with `::: layout`.");return t.length&&l.test(t[t.length-1].trim())&&t.pop(),{...h(e.trim()),items:L(t.join(`
|
|
5
|
+
`)),raw:n}},"parseLayoutBlock"),N=i(n=>{if(!n.startsWith("::: layout"))return null;const t=n.split(`
|
|
6
|
+
`);let e=0;const r=[];for(const o of t){const s=o.trim();if(r.push(o),a.test(s))e+=1;else if(l.test(s)&&(e-=1,e===0))return r.join(`
|
|
7
|
+
`)}return null},"readLayoutBlock");export{w as parseItemHeader,$ as parseLayoutBlock,h as parseLayoutHeader,d as parseOptions,N as readLayoutBlock};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var u=Object.defineProperty;var r=(t,o)=>u(t,"name",{value:o,configurable:!0});const s=r(t=>String(t).replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">"),"escapeAttribute"),l=r(t=>`--${t.replace(/[A-Z]/g,o=>`-${o.toLowerCase()}`)}`,"optionToStyleName"),y=r(t=>{const o=Object.entries(t).filter(([,a])=>typeof a!="boolean").map(([a,e])=>`${l(a)}: ${e};`);return o.length?` style="${s(o.join(" "))}"`:""},"optionsToStyle"),M=r((t,o)=>{const a=s(t.layoutType),e=t.items.map(n=>`<section class="bfs-layout-item"${n.name?` data-name="${s(n.name)}"`:""}${y(n.options)}>${o.renderMarkdown(n.body)}</section>`).join("");return`<div class="bfs-layout bfs-layout-${a}" data-layout="${a}"${y(t.options)}>${e}</div>`},"renderDefaultMarkdownLayout"),$=r((t,o,a={})=>{const e=a[t.layoutType];return e?e({type:t.layoutType,options:t.options,parts:o.renderParts(t),raw:t.raw},o):o.renderDefault(t)},"renderMarkdownLayout");export{M as renderDefaultMarkdownLayout,$ as renderMarkdownLayout};
|
|
File without changes
|
package/dist/esm/docs/run.js
CHANGED
|
@@ -1 +1,76 @@
|
|
|
1
|
-
var
|
|
1
|
+
var oe=Object.defineProperty;var c=(e,t)=>oe(e,"name",{value:t,configurable:!0});import{Marked as ae}from"marked";import{cp as F,mkdir as v,readdir as ne,readFile as M,writeFile as b}from"fs/promises";import o from"path";import ie from"front-matter";import le from"isomorphic-dompurify";import{markedHighlight as ce}from"marked-highlight";import Q from"highlight.js";import me from"./templates/default.template.js";import ue from"./renderer/index.js";import{createMarkdownLayoutExtension as pe}from"./markdown-layout/index.js";import fe from"clean-css";import de from"html-minifier";import*as X from"@putout/minify";import{fileURLToPath as he,pathToFileURL as A}from"url";import p from"fs";let K;const V=new fe({inline:["none"]}),R=new Map;R.set("default",me);let W;const ge=c((e,t)=>{if(!(!e&&!t))return{light:{...e?.light,...t?.light},dark:{...e?.dark,...t?.dark}}},"mergeTheme"),ye=c((e,t)=>({...e,...t,markdownLayouts:{...e.markdownLayouts,...t.markdownLayouts},scripts:{...e.scripts,...t.scripts},theme:ge(e.theme,t.theme)}),"mergeTemplateConfig"),we=c((e,t)=>{if(typeof e=="function")return!0;const{match:r}=e;return r?typeof r=="string"?t.includes(r):Array.isArray(r)?r.some(i=>t.includes(i)):r instanceof RegExp?r.test(t):r(t):!0},"scriptMatches"),ve=c((e,t)=>e?Object.values(e).filter(r=>r!==!1).filter(r=>we(r,t)).map(r=>typeof r=="function"?r():r.render()):[],"renderPageScripts"),G=c((e,t)=>{const r=Object.entries(t).filter(([i])=>i.startsWith("--")).map(([i,l])=>` ${i}: ${l};`).join(`
|
|
2
|
+
`);return r?`${e} {
|
|
3
|
+
${r}
|
|
4
|
+
}`:""},"renderThemeBlock"),xe=c(e=>{if(!e)return"";const t=e.light??e.dark,r=e.dark??e.light;return!t&&!r?"":[t?G(":root",t):"",r?`@media (prefers-color-scheme: dark) {
|
|
5
|
+
${G(" :root",r)}
|
|
6
|
+
}`:"",t?G('[data-theme="light"]',t):"",r?G('[data-theme="dark"]',r):""].filter(Boolean).join(`
|
|
7
|
+
|
|
8
|
+
`)},"renderThemeStylesheet"),Se=c((e="")=>String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"),"escapeXML"),be=c((e="")=>e.replace(/```[\s\S]*?```/g," ").replace(/`([^`]+)`/g,"$1").replace(/!\[[^\]]*]\([^)]*\)/g," ").replace(/\[([^\]]+)]\([^)]*\)/g,"$1").replace(/^#{1,6}\s+/gm,"").replace(/^---+$/gm," ").replace(/[>*_~]/g,"").replace(/\s+/g," ").trim(),"stripMarkdown"),De=c(e=>e==="/index.html"?"/":e.replace(/\/index\.html$/,"/").replace(/\.html$/,"").replace(/\/+/g,"/"),"pagePathToUrlPath"),Y=c((e,t)=>e?`${e.replace(/\/$/,"")}${t==="/"?"/":t}`:t,"canonicalUrl"),$e=c(async(e,t)=>p.existsSync(e)?(await v(o.dirname(t),{recursive:!0}),await F(e,t),!0):!1,"copyIfExists"),Pe=c(e=>{const t={sitemap:!0,robots:!0,llms:!0,llmsFull:!0,netlify:!1};return e===!1?{sitemap:!1,robots:!1,llms:!1,llmsFull:!1,netlify:!1}:e===!0||e===void 0?t:{...t,...e}},"normalizeGeneratedFilesConfig"),ke=c((e,t)=>{if(!t)return"";const r=new Date().toISOString().slice(0,10);return`<?xml version="1.0" encoding="UTF-8"?>
|
|
9
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
10
|
+
${e.map(l=>{const m=l.urlPath==="/"?"1.0":"0.8";return` <url>
|
|
11
|
+
<loc>${Se(Y(t,l.urlPath))}</loc>
|
|
12
|
+
<lastmod>${r}</lastmod>
|
|
13
|
+
<changefreq>weekly</changefreq>
|
|
14
|
+
<priority>${m}</priority>
|
|
15
|
+
</url>`}).join(`
|
|
16
|
+
`)}
|
|
17
|
+
</urlset>
|
|
18
|
+
`},"generateSitemap"),je=c(e=>`User-agent: *
|
|
19
|
+
Allow: /
|
|
20
|
+
${e?`
|
|
21
|
+
Sitemap: ${e.replace(/\/$/,"")}/sitemap.xml
|
|
22
|
+
Host: ${e.replace(/\/$/,"")}
|
|
23
|
+
`:""}
|
|
24
|
+
`,"generateRobots"),Te=c(e=>`# Documentation
|
|
25
|
+
|
|
26
|
+
## Page index
|
|
27
|
+
|
|
28
|
+
${e.map(t=>`- ${t.name}: ${t.urlPath} - ${t.description}`).join(`
|
|
29
|
+
`)}
|
|
30
|
+
`,"generateLlms"),Me=c((e,t)=>`# Documentation for AI agents
|
|
31
|
+
|
|
32
|
+
This file is generated at build time from the Markdown documentation. Use it to choose the most relevant page before reading the canonical HTML documentation.
|
|
33
|
+
|
|
34
|
+
${e.map(r=>`## ${r.title}
|
|
35
|
+
|
|
36
|
+
URL: ${Y(t,r.urlPath)}
|
|
37
|
+
Source: docs/${r.sourcePath}
|
|
38
|
+
Description: ${r.description}
|
|
39
|
+
|
|
40
|
+
${r.summary||r.description}
|
|
41
|
+
`).join(`
|
|
42
|
+
`)}
|
|
43
|
+
`,"generateLlmsFull"),Ce=c((e,t)=>{const r=["# Generated by @beforesemicolon/builder"];return[t.llms?"llms.txt":"",t.llmsFull?"llms-full.txt":"",t.sitemap?"sitemap.xml":"",t.robots?"robots.txt":""].filter(Boolean).forEach(l=>r.push(`/${l} /${l} 200`)),e.forEach(l=>{if(l.urlPath==="/")return;const m=l.urlPath.endsWith("/")?`${l.urlPath}index.html`:`${l.urlPath}.html`;r.push(`${l.urlPath} ${m} 200`),l.urlPath.endsWith("/")&&r.push(`${l.urlPath.replace(/\/$/,"")} ${m} 200`)}),`${[...new Set(r)].join(`
|
|
44
|
+
`)}
|
|
45
|
+
`},"generateNetlifyRedirects"),Fe=c(e=>`[build]
|
|
46
|
+
command = "node build-docs.js"
|
|
47
|
+
publish = "${e||"website"}"
|
|
48
|
+
|
|
49
|
+
[[headers]]
|
|
50
|
+
for = "/llms.txt"
|
|
51
|
+
|
|
52
|
+
[headers.values]
|
|
53
|
+
Content-Type = "text/plain; charset=utf-8"
|
|
54
|
+
Cache-Control = "public, max-age=0, must-revalidate"
|
|
55
|
+
|
|
56
|
+
[[headers]]
|
|
57
|
+
for = "/llms-full.txt"
|
|
58
|
+
|
|
59
|
+
[headers.values]
|
|
60
|
+
Content-Type = "text/plain; charset=utf-8"
|
|
61
|
+
Cache-Control = "public, max-age=0, must-revalidate"
|
|
62
|
+
|
|
63
|
+
[[headers]]
|
|
64
|
+
for = "/sitemap.xml"
|
|
65
|
+
|
|
66
|
+
[headers.values]
|
|
67
|
+
Content-Type = "application/xml; charset=utf-8"
|
|
68
|
+
Cache-Control = "public, max-age=0, must-revalidate"
|
|
69
|
+
|
|
70
|
+
[[headers]]
|
|
71
|
+
for = "/robots.txt"
|
|
72
|
+
|
|
73
|
+
[headers.values]
|
|
74
|
+
Content-Type = "text/plain; charset=utf-8"
|
|
75
|
+
Cache-Control = "public, max-age=0, must-revalidate"
|
|
76
|
+
`,"generateNetlifyToml"),D=c(async(e,t,r,i)=>{if(await $e(e,t))return;const l=r();if(!l){i&&console.warn(i);return}await v(o.dirname(t),{recursive:!0}),await b(t,l)},"writeGeneratedFile"),Ge=c(async({docsDir:e,docsSiteDir:t,pages:r,siteUrl:i,publicDir:l,generatedFiles:m})=>{m.sitemap&&await D(o.resolve(e,"sitemap.xml"),o.resolve(t,"sitemap.xml"),()=>ke(r,i),"Skipping generated sitemap.xml because buildDocs({ siteUrl }) is not set."),m.robots&&await D(o.resolve(e,"robots.txt"),o.resolve(t,"robots.txt"),()=>je(i)),m.llms&&await D(o.resolve(e,"llms.txt"),o.resolve(t,"llms.txt"),()=>Te(r)),m.llmsFull&&await D(o.resolve(e,"llms-full.txt"),o.resolve(t,"llms-full.txt"),()=>Me(r,i)),m.netlify&&(await D(o.resolve(e,"_redirects"),o.resolve(t,"_redirects"),()=>Ce(r,m)),await D(o.resolve(e,"netlify.toml"),o.resolve(t,"netlify.toml"),()=>Fe(l&&o.basename(l))))},"writeGeneratedDocsFiles"),Z=c((e={},t,r)=>{const i=new ae(ce({langPrefix:"hljs language-",highlight(l,m){const $=Q.getLanguage(m)?m:"plaintext";return Q.highlight(l,{language:$}).value}}));return i.use({renderer:ue}),i.use(pe({marked:i,handlers:e.markdownLayouts,renderMarkdown:r})),e.markedOptions&&i.use(e.markedOptions),t&&i.use(t),i},"createBaseMarked"),Ee=c((e={},t)=>{const r=Z(e,t),i=c(m=>r.parse(m),"renderMarkdown"),l=Z(e,t,i);return l.use({hooks:{postprocess(m){const{layout:$="default",...g}=W.attributes,P=ve(e.scripts,m);m=le.sanitize(m);const k=[...m.matchAll(/<h([0-6])\sid="[^"]+".*?>.*?<a\s+href="([^"]+)".*?>([^<]+)<\/a>/gm)].map(x=>({path:x[2],label:x[3],level:x[1]}));return R.get($)?.({...g,content:m,siteMap:W.siteMap,tableOfContent:k,projectMeta:K,renderMarkdown:i,scripts:P,themeStylesheet:e.theme?"/stylesheets/theme.css":void 0})||m}}}),l},"createMarked"),y=c(async e=>{const t=await ne(e),r=[];for(const i of t){const l=o.extname(i);/^[._]/.test(i)||(l?r.push(o.join(e,i)):/(stylesheets|assets|scripts)/.test(i)||r.push(...await y(o.join(e,i))))}return r},"traverseDirectory"),ot=c(async({srcDir:e,publicDir:t,markedOptions:r,template:i,siteUrl:l,generatedFiles:m}={})=>{try{const s=o.resolve(process.cwd(),"package.json");p.existsSync(s)&&(K=JSON.parse(await M(s,"utf-8")))}catch(s){console.warn("Failed to load project package.json metadata",s)}const $=c(()=>{try{return __dirname}catch{return o.dirname(he(import.meta.url))}},"getDirname"),g=i?o.resolve($(),"templates",i):null,P=g?o.resolve(g,"assets"):null,k=g?o.resolve(g,"stylesheets"):null,x=g?o.resolve(g,"layouts"):null;let j={};if(g)try{let s=o.resolve(g,"template.config.js");if(p.existsSync(s)||(s=s.replace(/\.js$/,".ts")),p.existsSync(s)){const a=await import(A(s).href);j=a.default||a}}catch(s){console.error(`Failed to load template config for ${i}`,s)}const f=e??o.resolve(process.cwd(),"docs"),u=t??o.resolve(process.cwd(),"website"),ee=Pe(m),w=o.resolve(f,"_template"),_=o.resolve(w,"assets"),B=o.resolve(w,"stylesheets"),N=o.resolve(w,"scripts"),U=o.resolve(w,"layouts"),z=o.resolve(f,"_layouts"),C=o.resolve(f,"assets"),q=o.resolve(f,"stylesheets"),E=o.resolve(f,"scripts");try{let s=o.resolve(w,"template.config.js");if(p.existsSync(s)||(s=s.replace(/\.js$/,".ts")),p.existsSync(s)){const a=await import(A(s).href),n=a.default||a;j=ye(j,n)}}catch(s){console.error("Failed to load docs _template config",s)}const te=Ee(j,r);if(await v(u,{recursive:!0}),P&&p.existsSync(P))try{await F(P,C.replace(f,u),{recursive:!0})}catch(s){console.warn(s)}if(p.existsSync(C))try{await F(C,C.replace(f,u),{recursive:!0})}catch(s){console.warn(s)}if(p.existsSync(_))try{await F(_,o.resolve(u,"assets"),{recursive:!0})}catch(s){console.warn(s)}try{const s=new Set;if(k&&p.existsSync(k)&&(await y(k)).forEach(n=>s.add(n)),p.existsSync(q)&&(await y(q)).forEach(n=>s.add(n)),p.existsSync(B)&&(await y(B)).forEach(n=>s.add(n)),s.size){await v(o.join(u,"stylesheets"),{recursive:!0});for(const n of s){const d=await M(n,"utf-8"),h=V.minify(d);h.errors.length&&h.errors.forEach(console.error);const T=n.startsWith(w)?n.replace(w,u):n.startsWith(f)?n.replace(f,u):o.join(u,"stylesheets",o.basename(n));await b(T,h.styles??d)}}const a=xe(j.theme);if(a){const n=V.minify(a);n.errors.length&&n.errors.forEach(console.error),await v(o.join(u,"stylesheets"),{recursive:!0}),await b(o.join(u,"stylesheets","theme.css"),n.styles??a)}}catch(s){console.error(s)}if(p.existsSync(E))try{const s=await y(E);s.length&&await v(E.replace(f,u),{recursive:!0});for(const a of s)try{const n=await M(a,"utf-8");await b(a.replace(f,u),X.minify(n))}catch(n){console.error(n)}}catch(s){console.warn(s)}if(p.existsSync(N))try{const s=await y(N);s.length&&await v(o.join(u,"scripts"),{recursive:!0});for(const a of s)try{const n=await M(a,"utf-8");await b(a.replace(w,u),X.minify(n))}catch(n){console.error(n)}}catch(s){console.warn(s)}try{const s=new Map;x&&p.existsSync(x)&&(await y(x)).forEach(a=>{/\.(j|t)s$/.test(a)&&s.set(o.basename(a).replace(/\.(j|t)s$/,""),a)}),p.existsSync(z)&&(await y(z)).forEach(a=>{/\.(j|t)s$/.test(a)&&s.set(o.basename(a).replace(/\.(j|t)s$/,""),a)}),p.existsSync(U)&&(await y(U)).forEach(a=>{/\.(j|t)s$/.test(a)&&s.set(o.basename(a).replace(/\.(j|t)s$/,""),a)});for(const[a,n]of s.entries()){const d=await import(A(n).href);R.set(a,d.default)}}catch(s){console.error("Template import failed",s)}const se=await y(f),H=new Map,I=(await Promise.all(se.filter(s=>s.endsWith(".md")).map(async s=>{const a=await M(s,"utf-8");return{filePath:s,...ie(a)}}))).sort((s,a)=>(s.attributes.order??0)-(a.attributes.order??0)).map(({attributes:s,body:a,filePath:n})=>{const d=n.replace(f,"").replace(/\.md/,".html"),h=n.replace(f,u).replace(".md",".html"),T=h.replace(o.basename(h),""),L=o.basename(d)||"/",re=d.replace(L,"").replace(/\/$/,"");let S=H;re.split("/").filter(Boolean).forEach(O=>{S.has(O)||S.set(O,new Map),S=S.get(O)});const J={...s,path:d};return S.has(L)||S.set(L,J),{attributes:J,fileWebsitePath:h,fileDirWebsitePath:T,body:a,sourcePath:o.relative(f,n),siteMap:H}});for(const{attributes:s,body:a,fileDirWebsitePath:n,fileWebsitePath:d,siteMap:h}of I){W={attributes:s,siteMap:h};const T=await te.parse(a);await v(n,{recursive:!0}),await b(d,de.minify(T,{includeAutoGeneratedTags:!0,removeAttributeQuotes:!0,removeComments:!0,removeRedundantAttributes:!0,removeScriptTypeAttributes:!0,removeStyleLinkTypeAttributes:!0,sortClassName:!0,useShortDoctype:!0,collapseWhitespace:!0,minifyJS:!0,minifyCSS:!0}))}await Ge({docsDir:f,docsSiteDir:u,pages:I.map(({attributes:s,body:a,sourcePath:n})=>{const d=De(String(s.path)),h=be(a);return{sourcePath:n,urlPath:d,title:String(s.title||s.name||"").trim()||"Documentation",name:String(s.name||s.title||"").trim()||"Documentation",description:String(s.description||"").trim()||h.slice(0,156)||"Documentation page.",order:Number(s.order??999),summary:h.slice(0,320)}}),siteUrl:l,publicDir:u,generatedFiles:ee})},"buildDocs");export{ot as buildDocs};
|
|
@@ -44,6 +44,59 @@ export const highlightLine = (line) => {
|
|
|
44
44
|
return tokens.join('')
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
export const renderCodeCopyScript = () => `
|
|
48
|
+
<script type="application/javascript">
|
|
49
|
+
(() => {
|
|
50
|
+
if (window.__fadingCitrusCodeCopyReady) return
|
|
51
|
+
window.__fadingCitrusCodeCopyReady = true
|
|
52
|
+
|
|
53
|
+
const showCopyButton = (snippet) => {
|
|
54
|
+
const copyBtn = snippet.querySelector('.code-copy-btn')
|
|
55
|
+
const hasCode = snippet.dataset.code || snippet.querySelector('code') || snippet.querySelector('.content')
|
|
56
|
+
if (copyBtn && hasCode) copyBtn.style.visibility = 'visible'
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
document.querySelectorAll('.code-snippet').forEach(showCopyButton)
|
|
60
|
+
|
|
61
|
+
document.addEventListener('click', (event) => {
|
|
62
|
+
const copyBtn = event.target.closest('.code-copy-btn')
|
|
63
|
+
if (!copyBtn) return
|
|
64
|
+
|
|
65
|
+
const snippet = copyBtn.closest('.code-snippet')
|
|
66
|
+
if (!snippet) return
|
|
67
|
+
|
|
68
|
+
let code = snippet.dataset.code ?? ''
|
|
69
|
+
|
|
70
|
+
if (!code) {
|
|
71
|
+
const codeEl = snippet.querySelector('code')
|
|
72
|
+
if (codeEl) {
|
|
73
|
+
const clone = codeEl.cloneNode(true)
|
|
74
|
+
clone.querySelectorAll('.line-number').forEach((el) => el.remove())
|
|
75
|
+
code = clone.textContent ?? ''
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!code) {
|
|
80
|
+
code = snippet.querySelector('.content')?.textContent ?? ''
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!code.trim().length) return
|
|
84
|
+
|
|
85
|
+
clearTimeout(copyBtn._timer)
|
|
86
|
+
navigator.clipboard.writeText(code.trim())
|
|
87
|
+
copyBtn.textContent = 'copied'
|
|
88
|
+
copyBtn.setAttribute('aria-label', 'Code copied')
|
|
89
|
+
copyBtn.classList.add('copied')
|
|
90
|
+
copyBtn._timer = setTimeout(() => {
|
|
91
|
+
copyBtn.textContent = 'copy'
|
|
92
|
+
copyBtn.setAttribute('aria-label', 'Copy code')
|
|
93
|
+
copyBtn.classList.remove('copied')
|
|
94
|
+
}, 1000)
|
|
95
|
+
})
|
|
96
|
+
})()
|
|
97
|
+
</script>
|
|
98
|
+
`
|
|
99
|
+
|
|
47
100
|
export const renderCodeBlock = (filename, code, lang = 'javascript') => {
|
|
48
101
|
const lines = code
|
|
49
102
|
.replace(/\n$/, '')
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
export const escapeHTML = (value = '') =>
|
|
2
|
+
String(value)
|
|
3
|
+
.replace(/&/g, '&')
|
|
4
|
+
.replace(/</g, '<')
|
|
5
|
+
.replace(/>/g, '>')
|
|
6
|
+
.replace(/"/g, '"')
|
|
7
|
+
.replace(/'/g, ''')
|
|
8
|
+
|
|
9
|
+
export const partByName = (parts, name) =>
|
|
10
|
+
parts.find((part) => part.name === name)
|
|
11
|
+
|
|
12
|
+
export const option = (value, fallback = '') =>
|
|
13
|
+
value === undefined || value === true ? fallback : String(value)
|
|
14
|
+
|
|
15
|
+
export const optionText = (value, fallback = '') =>
|
|
16
|
+
option(value, fallback).replace(/"/g, '"')
|
|
17
|
+
|
|
18
|
+
export const codeFromPart = (part = {}) => {
|
|
19
|
+
const match = String(part.body || '').match(
|
|
20
|
+
/(?:```|~~~)([^\n]*)\n([\s\S]*?)\n(?:```|~~~)/
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
if (!match) return ''
|
|
24
|
+
|
|
25
|
+
return match[2]
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const withFirstParagraphClass = (html = '', className = '') =>
|
|
29
|
+
html.replace(/<p>/, `<p class="${className}">`)
|
|
30
|
+
|
|
31
|
+
export const statContent = (html = '') => {
|
|
32
|
+
const value = html.match(/<h2[^>]*>([\s\S]*?)<\/h2>/)?.[1] || ''
|
|
33
|
+
const label = html.match(/<p[^>]*>([\s\S]*?)<\/p>/)?.[1] || ''
|
|
34
|
+
|
|
35
|
+
return `
|
|
36
|
+
<span class="stat-value text-gradient-primary">${value}</span>
|
|
37
|
+
<span class="stat-label">${label}</span>
|
|
38
|
+
`
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const stripHeadingLinks = (html = '') =>
|
|
42
|
+
html.replace(
|
|
43
|
+
/<h([1-6])([^>]*)><a href="[^"]*">([\s\S]*?)<\/a><\/h\1>/g,
|
|
44
|
+
'<h$1$2>$3</h$1>'
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
export const sectionHeader = (html = '') =>
|
|
48
|
+
stripHeadingLinks(html).replace(
|
|
49
|
+
/<p><code>([\s\S]*?)<\/code><\/p>/,
|
|
50
|
+
'<span class="section-tag font-mono">$1</span>'
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
export const groupedSectionHeader = (html = '') => {
|
|
54
|
+
const normalized = sectionHeader(html)
|
|
55
|
+
const match = normalized.match(
|
|
56
|
+
/^(\s*<span class="section-tag font-mono">[\s\S]*?<\/span>)(\s*<h2[^>]*>[\s\S]*?<\/h2>)([\s\S]*)$/
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
if (!match) return normalized
|
|
60
|
+
|
|
61
|
+
return `<div>${match[1]}${match[2]}</div>${match[3]}`
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export const icon = (name) => {
|
|
65
|
+
const icons = {
|
|
66
|
+
arrowRight:
|
|
67
|
+
'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>',
|
|
68
|
+
arrowUpRight:
|
|
69
|
+
'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17 17 7"/><path d="M7 7h10v10"/></svg>',
|
|
70
|
+
book: '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>',
|
|
71
|
+
terminal:
|
|
72
|
+
'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/></svg>',
|
|
73
|
+
sparkles:
|
|
74
|
+
'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="sparkles-icon"><path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275Z"/><path d="m5 3 1 2.5L8.5 6 6 7 5 9.5 4 7 1.5 6 4 5Z"/><path d="m19 17 1 2.5 2.5.5-2.5 1-1 2.5-1-2.5-2.5-1 2.5-1Z"/></svg>',
|
|
75
|
+
webComponents:
|
|
76
|
+
'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5.5 8.5 9 12l-3.5 3.5L2 12l3.5-3.5Z"/><path d="m12 2 3.5 3.5L12 9 8.5 5.5 12 2Z"/><path d="M18.5 8.5 22 12l-3.5 3.5L15 12l3.5-3.5Z"/><path d="m12 15 3.5 3.5-3.5 3.5-3.5-3.5 3.5-3.5Z"/></svg>',
|
|
77
|
+
router: '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="19" r="3"/><circle cx="18" cy="5" r="3"/><path d="M9 19h8.5a3.5 3.5 0 0 0 3.5-3.5V8.5a3.5 3.5 0 0 0-3.5-3.5H9"/></svg>',
|
|
78
|
+
reactive:
|
|
79
|
+
'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>',
|
|
80
|
+
tiny: '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.24 12.24a6 6 0 0 0-8.49-8.49L5 10.5V19h8.5z"/><line x1="16" y1="8" x2="2" y2="22"/><line x1="17.5" y1="15" x2="9" y2="15"/></svg>',
|
|
81
|
+
standards:
|
|
82
|
+
'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8.3 10a3.5 3.5 0 0 1 0-7h7.4a3.5 3.5 0 0 1 0 7H8.3Z"/><path d="M12 14a3 3 0 0 1 3-3h3.5a3 3 0 0 1 3 3v3.5a3 3 0 0 1-3 3H15a3 3 0 0 1-3-3V14Z"/><path d="M2 14.5a3.5 3.5 0 0 1 7 0v2.8a3.5 3.5 0 0 1-7 0v-2.8Z"/></svg>',
|
|
83
|
+
plug: '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22v-5"/><path d="M9 8V2"/><path d="M15 8V2"/><path d="M18 8H6v5a4 4 0 0 0 4 4h4a4 4 0 0 0 4-4Z"/></svg>',
|
|
84
|
+
surgical:
|
|
85
|
+
'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m12 14 4-4"/><path d="M3.34 19a10 10 0 1 1 17.32 0"/></svg>',
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return icons[name] || icons.reactive
|
|
89
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import meta from './_head-meta.js'
|
|
2
2
|
import header from './_header.js'
|
|
3
3
|
import footer from './_footer.js'
|
|
4
|
-
import copyCode from './_copy-code.js'
|
|
5
4
|
|
|
6
5
|
const githubDocsPath =
|
|
7
6
|
'https://github.com/beforesemicolon/markup/tree/main/docs'
|
|
@@ -47,6 +46,11 @@ export default (props) => {
|
|
|
47
46
|
<head>
|
|
48
47
|
${meta(props)}
|
|
49
48
|
<link rel="stylesheet" href="/stylesheets/documentation.css?v=20260621exact">
|
|
49
|
+
${
|
|
50
|
+
props.themeStylesheet
|
|
51
|
+
? `<link rel="stylesheet" href="${props.themeStylesheet}">`
|
|
52
|
+
: ''
|
|
53
|
+
}
|
|
50
54
|
</head>
|
|
51
55
|
<body>
|
|
52
56
|
${header(props)}
|
|
@@ -83,8 +87,7 @@ export default (props) => {
|
|
|
83
87
|
</main>
|
|
84
88
|
|
|
85
89
|
${footer()}
|
|
86
|
-
|
|
87
|
-
${copyCode()}
|
|
90
|
+
${props.scripts?.join('') || ''}
|
|
88
91
|
|
|
89
92
|
</body>
|
|
90
93
|
</html>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { icon, partByName } from './_layout-utils.js'
|
|
2
|
+
|
|
3
|
+
export default ({ parts, options }) => {
|
|
4
|
+
const copy = partByName(parts, 'copy') || parts[0]
|
|
5
|
+
const title = options.title || ''
|
|
6
|
+
const title2 = options.title2 || ''
|
|
7
|
+
|
|
8
|
+
return `
|
|
9
|
+
<section class="cta-section wrapper">
|
|
10
|
+
<div class="cta-card">
|
|
11
|
+
<div class="cta-glow"></div>
|
|
12
|
+
<h2>
|
|
13
|
+
<span class="text-gradient">${title}</span>
|
|
14
|
+
<span class="text-gradient-primary">${title2}</span>
|
|
15
|
+
</h2>
|
|
16
|
+
${copy?.html || ''}
|
|
17
|
+
<div class="cta-buttons">
|
|
18
|
+
<a href="/documentation/get-started" class="btn-primary">
|
|
19
|
+
<span>Get Started</span>
|
|
20
|
+
${icon('arrowRight')}
|
|
21
|
+
</a>
|
|
22
|
+
<a href="/documentation/index.html?v=20260621exact" class="btn-outline">
|
|
23
|
+
${icon('book')}
|
|
24
|
+
<span>Read the Docs</span>
|
|
25
|
+
</a>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</section>
|
|
29
|
+
`
|
|
30
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
groupedSectionHeader,
|
|
3
|
+
icon,
|
|
4
|
+
option,
|
|
5
|
+
partByName,
|
|
6
|
+
} from './_layout-utils.js'
|
|
7
|
+
|
|
8
|
+
export default ({ parts }) => {
|
|
9
|
+
const header = partByName(parts, 'header') || parts[0]
|
|
10
|
+
const cards = parts.filter((part) => part.name === 'product')
|
|
11
|
+
|
|
12
|
+
return `
|
|
13
|
+
<section class="products-section wrapper">
|
|
14
|
+
<div class="section-header">${groupedSectionHeader(header?.html || '')}</div>
|
|
15
|
+
<div class="products-grid">
|
|
16
|
+
${cards
|
|
17
|
+
.map(
|
|
18
|
+
(card) => `
|
|
19
|
+
<div class="product-card card-${option(card.options.color, 'orange')}">
|
|
20
|
+
<div class="product-glow"></div>
|
|
21
|
+
<a href="${option(card.options.href, '#')}" target="_blank" rel="noreferrer" class="product-head">
|
|
22
|
+
<div class="product-title-row">
|
|
23
|
+
<div class="icon-container">${icon(option(card.options.icon, 'webComponents'))}</div>
|
|
24
|
+
<div>
|
|
25
|
+
<h3>${option(card.options.title, card.name || '')}</h3>
|
|
26
|
+
<span class="package-name font-mono">${option(card.options.package, '')}</span>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
<span class="product-arrow">${icon('arrowUpRight')}</span>
|
|
30
|
+
</a>
|
|
31
|
+
${card.html}
|
|
32
|
+
<a href="${option(card.options.href, '#')}" target="_blank" rel="noreferrer" class="product-link">
|
|
33
|
+
<span>Read the docs</span>
|
|
34
|
+
${icon('arrowUpRight')}
|
|
35
|
+
</a>
|
|
36
|
+
</div>
|
|
37
|
+
`
|
|
38
|
+
)
|
|
39
|
+
.join('')}
|
|
40
|
+
</div>
|
|
41
|
+
</section>
|
|
42
|
+
`
|
|
43
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { icon, option, partByName, sectionHeader } from './_layout-utils.js'
|
|
2
|
+
|
|
3
|
+
export default ({ parts }) => {
|
|
4
|
+
const header = partByName(parts, 'header') || parts[0]
|
|
5
|
+
const features = parts.filter((part) => part.name === 'feature')
|
|
6
|
+
|
|
7
|
+
return `
|
|
8
|
+
<section id="features" class="features-section wrapper">
|
|
9
|
+
<div class="section-header">${sectionHeader(header?.html || '')}</div>
|
|
10
|
+
<div class="features-grid">
|
|
11
|
+
${features
|
|
12
|
+
.map(
|
|
13
|
+
(feature) => `
|
|
14
|
+
<div class="feature-card">
|
|
15
|
+
<div class="feature-border"></div>
|
|
16
|
+
<div class="icon-box">${icon(option(feature.options.icon, 'reactive'))}</div>
|
|
17
|
+
${feature.html}
|
|
18
|
+
</div>
|
|
19
|
+
`
|
|
20
|
+
)
|
|
21
|
+
.join('')}
|
|
22
|
+
</div>
|
|
23
|
+
</section>
|
|
24
|
+
`
|
|
25
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { renderCodeBlock } from './_code-snippet.js'
|
|
2
|
+
import {
|
|
3
|
+
codeFromPart,
|
|
4
|
+
icon,
|
|
5
|
+
option,
|
|
6
|
+
partByName,
|
|
7
|
+
statContent,
|
|
8
|
+
withFirstParagraphClass,
|
|
9
|
+
} from './_layout-utils.js'
|
|
10
|
+
|
|
11
|
+
export default ({ parts, options }) => {
|
|
12
|
+
const copy = partByName(parts, 'copy') || parts[0]
|
|
13
|
+
const code = partByName(parts, 'code') || parts[1]
|
|
14
|
+
const stats = parts.filter((part) => part.name === 'stat')
|
|
15
|
+
const version = option(options.version)
|
|
16
|
+
const title = option(options.title, '')
|
|
17
|
+
const title2 = option(options.title2, '')
|
|
18
|
+
const primaryHref = option(
|
|
19
|
+
options.primaryHref,
|
|
20
|
+
'/documentation/get-started'
|
|
21
|
+
)
|
|
22
|
+
const primaryLabel = option(options.primaryLabel, 'Get Started')
|
|
23
|
+
const secondaryLabel = option(
|
|
24
|
+
options.secondaryLabel,
|
|
25
|
+
'npm i @beforesemicolon/markup'
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
return `
|
|
29
|
+
<section class="hero-section relative overflow-hidden">
|
|
30
|
+
<div class="absolute inset-0 bg-grid pointer-events-none"></div>
|
|
31
|
+
<div class="absolute inset-0 hero-glow pointer-events-none animate-pulse-glow"></div>
|
|
32
|
+
<div class="wrapper hero-container animate-float-up">
|
|
33
|
+
<div class="hero-content">
|
|
34
|
+
${
|
|
35
|
+
version
|
|
36
|
+
? `<a href="https://github.com/beforesemicolon/markup" target="_blank" rel="noopener" class="version-badge">
|
|
37
|
+
${icon('sparkles')}
|
|
38
|
+
<span>${version}</span>
|
|
39
|
+
${icon('arrowRight')}
|
|
40
|
+
</a>`
|
|
41
|
+
: ''
|
|
42
|
+
}
|
|
43
|
+
<h1 class="hero-title">
|
|
44
|
+
<span class="text-gradient">${title}</span><br/>
|
|
45
|
+
<span class="text-gradient-primary">${title2}</span>
|
|
46
|
+
</h1>
|
|
47
|
+
${withFirstParagraphClass(copy?.html || '', 'hero-subtitle')}
|
|
48
|
+
<div class="hero-actions">
|
|
49
|
+
<a href="${primaryHref}" class="btn-primary">
|
|
50
|
+
<span>${primaryLabel}</span>
|
|
51
|
+
${icon('arrowRight')}
|
|
52
|
+
</a>
|
|
53
|
+
<a href="#install" class="btn-secondary font-mono">${secondaryLabel}</a>
|
|
54
|
+
</div>
|
|
55
|
+
${
|
|
56
|
+
stats.length
|
|
57
|
+
? `<div class="hero-stats">${stats
|
|
58
|
+
.map(
|
|
59
|
+
(stat, index) => `
|
|
60
|
+
${index ? '<div class="stat-divider"></div>' : ''}
|
|
61
|
+
<div class="stat-item">${statContent(stat.html)}</div>
|
|
62
|
+
`
|
|
63
|
+
)
|
|
64
|
+
.join('')}</div>`
|
|
65
|
+
: ''
|
|
66
|
+
}
|
|
67
|
+
</div>
|
|
68
|
+
${
|
|
69
|
+
code
|
|
70
|
+
? `<div class="hero-code-panel">
|
|
71
|
+
<div class="glow-container">
|
|
72
|
+
<div class="absolute inset-0 bg-gradient-to-br from-primary/20 to-accent/20 blur-3xl rounded-full"></div>
|
|
73
|
+
</div>
|
|
74
|
+
${renderCodeBlock(option(code.options.filename, ''), codeFromPart(code), option(code.options.lang, 'javascript'))}
|
|
75
|
+
</div>`
|
|
76
|
+
: ''
|
|
77
|
+
}
|
|
78
|
+
</div>
|
|
79
|
+
</section>
|
|
80
|
+
`
|
|
81
|
+
}
|