@beforesemicolon/builder 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/README.md +33 -30
  2. package/dist/cjs/build-modules.js +1 -1
  3. package/dist/cjs/docs/run.js +1 -1
  4. package/dist/cjs/docs/templates/fading-citrus/assets/before-semicolon-logo.png +0 -0
  5. package/dist/cjs/docs/templates/fading-citrus/assets/client-server.svg +4 -0
  6. package/dist/cjs/docs/templates/fading-citrus/assets/facebook.svg +8 -0
  7. package/dist/cjs/docs/templates/fading-citrus/assets/fast.svg +4 -0
  8. package/dist/cjs/docs/templates/fading-citrus/assets/favicon/android-chrome-192x192.png +0 -0
  9. package/dist/cjs/docs/templates/fading-citrus/assets/favicon/android-chrome-512x512.png +0 -0
  10. package/dist/cjs/docs/templates/fading-citrus/assets/favicon/apple-touch-icon.png +0 -0
  11. package/dist/cjs/docs/templates/fading-citrus/assets/favicon/favicon-16x16.png +0 -0
  12. package/dist/cjs/docs/templates/fading-citrus/assets/favicon/favicon-32x32.png +0 -0
  13. package/dist/cjs/docs/templates/fading-citrus/assets/favicon/favicon.ico +0 -0
  14. package/dist/cjs/docs/templates/fading-citrus/assets/favicon/site.webmanifest +19 -0
  15. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Black.otf +0 -0
  16. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-BlackItalic.otf +0 -0
  17. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Bold.otf +0 -0
  18. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-BoldItalic.otf +0 -0
  19. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ExtraBold.otf +0 -0
  20. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ExtraBoldItalic.otf +0 -0
  21. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ExtraLight.otf +0 -0
  22. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ExtraLightItalic.otf +0 -0
  23. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Italic.otf +0 -0
  24. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Light.otf +0 -0
  25. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-LightItalic.otf +0 -0
  26. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Medium.otf +0 -0
  27. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-MediumItalic.otf +0 -0
  28. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Regular.otf +0 -0
  29. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-SemiBold.otf +0 -0
  30. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-SemiBoldItalic.otf +0 -0
  31. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Thin.otf +0 -0
  32. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ThinItalic.otf +0 -0
  33. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/SIL Open Font License.txt +43 -0
  34. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/Apache License.txt +201 -0
  35. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Bold.ttf +0 -0
  36. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-BoldItalic.ttf +0 -0
  37. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-ExtraBold.ttf +0 -0
  38. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-ExtraBoldItalic.ttf +0 -0
  39. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Italic.ttf +0 -0
  40. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Light.ttf +0 -0
  41. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-LightItalic.ttf +0 -0
  42. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Regular.ttf +0 -0
  43. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Semibold.ttf +0 -0
  44. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-SemiboldItalic.ttf +0 -0
  45. package/dist/cjs/docs/templates/fading-citrus/assets/independent.svg +23 -0
  46. package/dist/cjs/docs/templates/fading-citrus/assets/instagram.svg +28 -0
  47. package/dist/cjs/docs/templates/fading-citrus/assets/markup-banner.jpg +0 -0
  48. package/dist/cjs/docs/templates/fading-citrus/assets/markup-essentials-training.jpg +0 -0
  49. package/dist/cjs/docs/templates/fading-citrus/assets/markup-favicon.jpg +0 -0
  50. package/dist/cjs/docs/templates/fading-citrus/assets/markup-favicon.png +0 -0
  51. package/dist/cjs/docs/templates/fading-citrus/assets/markup-logo-name.svg +10 -0
  52. package/dist/cjs/docs/templates/fading-citrus/assets/markup-logo-name@2x.png +0 -0
  53. package/dist/cjs/docs/templates/fading-citrus/assets/markup-logo.svg +13 -0
  54. package/dist/cjs/docs/templates/fading-citrus/assets/markup-logo@2x.png +0 -0
  55. package/dist/cjs/docs/templates/fading-citrus/assets/medium2.svg +18 -0
  56. package/dist/cjs/docs/templates/fading-citrus/assets/reactive.svg +3 -0
  57. package/dist/cjs/docs/templates/fading-citrus/assets/reddit.svg +16 -0
  58. package/dist/cjs/docs/templates/fading-citrus/assets/simple.svg +8 -0
  59. package/dist/cjs/docs/templates/fading-citrus/assets/small.svg +8 -0
  60. package/dist/cjs/docs/templates/fading-citrus/assets/twitter.svg +11 -0
  61. package/dist/cjs/docs/templates/fading-citrus/assets/youtube.svg +10 -0
  62. package/dist/cjs/docs/templates/fading-citrus/layouts/_code-snippet.js +75 -0
  63. package/dist/cjs/docs/templates/fading-citrus/layouts/_copy-code.js +50 -0
  64. package/dist/cjs/docs/templates/fading-citrus/layouts/_footer.js +72 -0
  65. package/dist/cjs/docs/templates/fading-citrus/layouts/_head-meta.js +231 -0
  66. package/dist/cjs/docs/templates/fading-citrus/layouts/_header.js +41 -0
  67. package/dist/cjs/docs/templates/fading-citrus/layouts/_logo.js +31 -0
  68. package/dist/cjs/docs/templates/fading-citrus/layouts/document.js +92 -0
  69. package/dist/cjs/docs/templates/fading-citrus/layouts/landing.js +636 -0
  70. package/dist/cjs/docs/templates/fading-citrus/stylesheets/common.css +814 -0
  71. package/dist/cjs/docs/templates/fading-citrus/stylesheets/documentation.css +603 -0
  72. package/dist/cjs/docs/templates/fading-citrus/stylesheets/fonts.css +1 -0
  73. package/dist/cjs/docs/templates/fading-citrus/stylesheets/github-dark.hightlighter.css +107 -0
  74. package/dist/cjs/docs/templates/fading-citrus/stylesheets/github-light.hightlighter.css +107 -0
  75. package/dist/cjs/docs/templates/fading-citrus/stylesheets/hybrid.hightlighter.css +102 -0
  76. package/dist/cjs/docs/templates/fading-citrus/stylesheets/landing.css +1553 -0
  77. package/dist/cjs/docs/templates/fading-citrus/stylesheets/normalize.css +351 -0
  78. package/dist/cjs/docs/templates/fading-citrus/template.config.js +14 -0
  79. package/dist/cjs/docs/types.js +1 -1
  80. package/dist/esm/build-modules.js +1 -1
  81. package/dist/esm/docs/run.js +1 -1
  82. package/dist/esm/docs/templates/fading-citrus/assets/before-semicolon-logo.png +0 -0
  83. package/dist/esm/docs/templates/fading-citrus/assets/client-server.svg +4 -0
  84. package/dist/esm/docs/templates/fading-citrus/assets/facebook.svg +8 -0
  85. package/dist/esm/docs/templates/fading-citrus/assets/fast.svg +4 -0
  86. package/dist/esm/docs/templates/fading-citrus/assets/favicon/android-chrome-192x192.png +0 -0
  87. package/dist/esm/docs/templates/fading-citrus/assets/favicon/android-chrome-512x512.png +0 -0
  88. package/dist/esm/docs/templates/fading-citrus/assets/favicon/apple-touch-icon.png +0 -0
  89. package/dist/esm/docs/templates/fading-citrus/assets/favicon/favicon-16x16.png +0 -0
  90. package/dist/esm/docs/templates/fading-citrus/assets/favicon/favicon-32x32.png +0 -0
  91. package/dist/esm/docs/templates/fading-citrus/assets/favicon/favicon.ico +0 -0
  92. package/dist/esm/docs/templates/fading-citrus/assets/favicon/site.webmanifest +19 -0
  93. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Black.otf +0 -0
  94. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-BlackItalic.otf +0 -0
  95. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Bold.otf +0 -0
  96. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-BoldItalic.otf +0 -0
  97. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ExtraBold.otf +0 -0
  98. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ExtraBoldItalic.otf +0 -0
  99. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ExtraLight.otf +0 -0
  100. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ExtraLightItalic.otf +0 -0
  101. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Italic.otf +0 -0
  102. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Light.otf +0 -0
  103. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-LightItalic.otf +0 -0
  104. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Medium.otf +0 -0
  105. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-MediumItalic.otf +0 -0
  106. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Regular.otf +0 -0
  107. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-SemiBold.otf +0 -0
  108. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-SemiBoldItalic.otf +0 -0
  109. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Thin.otf +0 -0
  110. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ThinItalic.otf +0 -0
  111. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/SIL Open Font License.txt +43 -0
  112. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/Apache License.txt +201 -0
  113. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Bold.ttf +0 -0
  114. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-BoldItalic.ttf +0 -0
  115. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-ExtraBold.ttf +0 -0
  116. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-ExtraBoldItalic.ttf +0 -0
  117. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Italic.ttf +0 -0
  118. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Light.ttf +0 -0
  119. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-LightItalic.ttf +0 -0
  120. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Regular.ttf +0 -0
  121. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Semibold.ttf +0 -0
  122. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-SemiboldItalic.ttf +0 -0
  123. package/dist/esm/docs/templates/fading-citrus/assets/independent.svg +23 -0
  124. package/dist/esm/docs/templates/fading-citrus/assets/instagram.svg +28 -0
  125. package/dist/esm/docs/templates/fading-citrus/assets/markup-banner.jpg +0 -0
  126. package/dist/esm/docs/templates/fading-citrus/assets/markup-essentials-training.jpg +0 -0
  127. package/dist/esm/docs/templates/fading-citrus/assets/markup-favicon.jpg +0 -0
  128. package/dist/esm/docs/templates/fading-citrus/assets/markup-favicon.png +0 -0
  129. package/dist/esm/docs/templates/fading-citrus/assets/markup-logo-name.svg +10 -0
  130. package/dist/esm/docs/templates/fading-citrus/assets/markup-logo-name@2x.png +0 -0
  131. package/dist/esm/docs/templates/fading-citrus/assets/markup-logo.svg +13 -0
  132. package/dist/esm/docs/templates/fading-citrus/assets/markup-logo@2x.png +0 -0
  133. package/dist/esm/docs/templates/fading-citrus/assets/medium2.svg +18 -0
  134. package/dist/esm/docs/templates/fading-citrus/assets/reactive.svg +3 -0
  135. package/dist/esm/docs/templates/fading-citrus/assets/reddit.svg +16 -0
  136. package/dist/esm/docs/templates/fading-citrus/assets/simple.svg +8 -0
  137. package/dist/esm/docs/templates/fading-citrus/assets/small.svg +8 -0
  138. package/dist/esm/docs/templates/fading-citrus/assets/twitter.svg +11 -0
  139. package/dist/esm/docs/templates/fading-citrus/assets/youtube.svg +10 -0
  140. package/dist/esm/docs/templates/fading-citrus/layouts/_code-snippet.js +75 -0
  141. package/dist/esm/docs/templates/fading-citrus/layouts/_copy-code.js +50 -0
  142. package/dist/esm/docs/templates/fading-citrus/layouts/_footer.js +72 -0
  143. package/dist/esm/docs/templates/fading-citrus/layouts/_head-meta.js +231 -0
  144. package/dist/esm/docs/templates/fading-citrus/layouts/_header.js +41 -0
  145. package/dist/esm/docs/templates/fading-citrus/layouts/_logo.js +31 -0
  146. package/dist/esm/docs/templates/fading-citrus/layouts/document.js +92 -0
  147. package/dist/esm/docs/templates/fading-citrus/layouts/landing.js +636 -0
  148. package/dist/esm/docs/templates/fading-citrus/stylesheets/common.css +814 -0
  149. package/dist/esm/docs/templates/fading-citrus/stylesheets/documentation.css +603 -0
  150. package/dist/esm/docs/templates/fading-citrus/stylesheets/fonts.css +1 -0
  151. package/dist/esm/docs/templates/fading-citrus/stylesheets/github-dark.hightlighter.css +107 -0
  152. package/dist/esm/docs/templates/fading-citrus/stylesheets/github-light.hightlighter.css +107 -0
  153. package/dist/esm/docs/templates/fading-citrus/stylesheets/hybrid.hightlighter.css +102 -0
  154. package/dist/esm/docs/templates/fading-citrus/stylesheets/landing.css +1553 -0
  155. package/dist/esm/docs/templates/fading-citrus/stylesheets/normalize.css +351 -0
  156. package/dist/esm/docs/templates/fading-citrus/template.config.js +14 -0
  157. package/dist/types/build-browser.d.ts +1 -1
  158. package/dist/types/build-modules.d.ts +1 -1
  159. package/dist/types/docs/run.d.ts +2 -1
  160. package/dist/types/docs/types.d.ts +28 -6
  161. package/package.json +1 -1
@@ -0,0 +1,231 @@
1
+ /* global process */
2
+ const isDev = process.env.NODE_ENV === 'development'
3
+
4
+ const siteUrl = 'https://markup.beforesemicolon.com'
5
+ const siteName = 'Markup'
6
+ const defaultTitle = 'Markup by Before Semicolon'
7
+ const defaultDescription =
8
+ 'Markup is a tiny reactive HTML templating system for building JavaScript user interfaces with web standards, no JSX, and no build step.'
9
+ const defaultImage = `${siteUrl}/assets/markup-banner.jpg`
10
+ const baseKeywords = [
11
+ 'Markup',
12
+ '@beforesemicolon/markup',
13
+ 'reactive HTML',
14
+ 'JavaScript templating',
15
+ 'template literals',
16
+ 'web components',
17
+ 'state management',
18
+ 'no build step',
19
+ 'vanilla JavaScript',
20
+ ]
21
+
22
+ const escapeHTML = (value = '') =>
23
+ String(value)
24
+ .replace(/&/g, '&')
25
+ .replace(/</g, '&lt;')
26
+ .replace(/>/g, '&gt;')
27
+ .replace(/"/g, '&quot;')
28
+ .replace(/'/g, '&#39;')
29
+
30
+ const canonicalPath = (path = '/') => {
31
+ const cleanPath = path.split('?')[0].split('#')[0] || '/'
32
+
33
+ if (cleanPath === '/index.html') return '/'
34
+ if (cleanPath.endsWith('/index.html')) {
35
+ return cleanPath.replace(/index\.html$/, '')
36
+ }
37
+
38
+ return cleanPath.replace(/\.html$/, '')
39
+ }
40
+
41
+ const absoluteUrl = (path = '/') => `${siteUrl}${canonicalPath(path)}`
42
+
43
+ const compactDescription = (description) =>
44
+ (description || defaultDescription).replace(/\s+/g, ' ').trim()
45
+
46
+ const pageKeywords = ({ title, name, keywords } = {}) => {
47
+ const values = [
48
+ ...baseKeywords,
49
+ title?.replace(/ - Markup by Before Semicolon$/, ''),
50
+ name,
51
+ ...(Array.isArray(keywords)
52
+ ? keywords
53
+ : String(keywords || '').split(',')),
54
+ ]
55
+
56
+ return [...new Set(values.map((value) => value?.trim()).filter(Boolean))]
57
+ .slice(0, 18)
58
+ .join(', ')
59
+ }
60
+
61
+ const jsonScript = (data) =>
62
+ `<script type="application/ld+json">${JSON.stringify(data)
63
+ .replace(/</g, '\\u003c')
64
+ .replace(/>/g, '\\u003e')
65
+ .replace(/&/g, '\\u0026')}</script>`
66
+
67
+ const breadcrumbJson = ({ title, path }) => {
68
+ const cleanPath = canonicalPath(path)
69
+ const parts = cleanPath.split('/').filter(Boolean)
70
+ const items = [
71
+ {
72
+ '@type': 'ListItem',
73
+ position: 1,
74
+ name: 'Home',
75
+ item: siteUrl,
76
+ },
77
+ ]
78
+
79
+ let current = ''
80
+ parts.forEach((part, index) => {
81
+ current += `/${part}`
82
+ items.push({
83
+ '@type': 'ListItem',
84
+ position: index + 2,
85
+ name:
86
+ index === parts.length - 1
87
+ ? title.replace(/ - Markup by Before Semicolon$/, '')
88
+ : part
89
+ .split('-')
90
+ .map((word) => word[0]?.toUpperCase() + word.slice(1))
91
+ .join(' '),
92
+ item: `${siteUrl}${current}`,
93
+ })
94
+ })
95
+
96
+ return {
97
+ '@context': 'https://schema.org',
98
+ '@type': 'BreadcrumbList',
99
+ itemListElement: items,
100
+ }
101
+ }
102
+
103
+ const pageJson = ({ title, description, path, name }) => {
104
+ const isDocsPage = canonicalPath(path).startsWith('/documentation')
105
+ const url = absoluteUrl(path)
106
+
107
+ if (isDocsPage) {
108
+ return {
109
+ '@context': 'https://schema.org',
110
+ '@type': 'TechArticle',
111
+ headline: title,
112
+ name: name || title,
113
+ description,
114
+ url,
115
+ image: defaultImage,
116
+ inLanguage: 'en-US',
117
+ isPartOf: {
118
+ '@type': 'TechArticle',
119
+ name: 'Markup Documentation',
120
+ url: `${siteUrl}/documentation`,
121
+ },
122
+ about: [
123
+ 'Reactive HTML templating',
124
+ 'JavaScript template literals',
125
+ 'Markup state and effect APIs',
126
+ 'Web Components',
127
+ ],
128
+ publisher: {
129
+ '@type': 'Organization',
130
+ name: 'Before Semicolon',
131
+ url: 'https://beforesemicolon.com',
132
+ logo: {
133
+ '@type': 'ImageObject',
134
+ url: `${siteUrl}/assets/before-semicolon-logo.png`,
135
+ },
136
+ },
137
+ mainEntityOfPage: url,
138
+ }
139
+ }
140
+
141
+ return {
142
+ '@context': 'https://schema.org',
143
+ '@type': 'SoftwareSourceCode',
144
+ name: 'Markup',
145
+ alternateName: '@beforesemicolon/markup',
146
+ description,
147
+ url,
148
+ image: defaultImage,
149
+ codeRepository: 'https://github.com/beforesemicolon/markup',
150
+ programmingLanguage: 'JavaScript',
151
+ runtimePlatform: 'Browser and Node.js',
152
+ license: 'https://github.com/beforesemicolon/markup/blob/main/LICENSE',
153
+ publisher: {
154
+ '@type': 'Organization',
155
+ name: 'Before Semicolon',
156
+ url: 'https://beforesemicolon.com',
157
+ },
158
+ }
159
+ }
160
+
161
+ export default (props = {}) => {
162
+ const title = props.title || defaultTitle
163
+ const description = compactDescription(props.description)
164
+ const url = absoluteUrl(props.path)
165
+ const canonical = escapeHTML(url)
166
+ const image = props.image || defaultImage
167
+ const type = canonicalPath(props.path).startsWith('/documentation')
168
+ ? 'article'
169
+ : 'website'
170
+
171
+ return `
172
+ <meta charset="UTF-8" />
173
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
174
+ <meta http-equiv="X-UA-Compatible" content="ie=edge" />
175
+ <title>${escapeHTML(title)}</title>
176
+ <meta name="description" content="${escapeHTML(description)}" />
177
+ <meta name="keywords" content="${escapeHTML(pageKeywords(props))}" />
178
+ <meta name="robots" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1" />
179
+ <meta name="googlebot" content="index, follow" />
180
+ <meta name="author" content="Before Semicolon" />
181
+ <meta name="publisher" content="Before Semicolon" />
182
+ <meta name="application-name" content="${siteName}" />
183
+ <meta name="generator" content="@beforesemicolon/builder" />
184
+ <meta name="theme-color" content="#080d12" />
185
+ <meta name="color-scheme" content="dark light" />
186
+ <link rel="canonical" href="${canonical}" />
187
+ <link rel="home" href="${siteUrl}/" />
188
+ <link rel="sitemap" type="application/xml" href="/sitemap.xml" />
189
+ <link rel="alternate" type="text/plain" title="LLMs guide" href="/llms.txt" />
190
+ <link rel="alternate" type="text/plain" title="Full LLM documentation export" href="/llms-full.txt" />
191
+ <meta property="og:title" content="${escapeHTML(title)}" />
192
+ <meta property="og:type" content="${type}" />
193
+ <meta property="og:description" content="${escapeHTML(description)}" />
194
+ <meta property="og:image" content="${escapeHTML(image)}" />
195
+ <meta property="og:image:secure_url" content="${escapeHTML(image)}" />
196
+ <meta property="og:image:width" content="1200" />
197
+ <meta property="og:image:height" content="630" />
198
+ <meta property="og:image:alt" content="${escapeHTML(title)}" />
199
+ <meta property="og:url" content="${canonical}" />
200
+ <meta property="og:site_name" content="${siteName}" />
201
+ <meta property="og:locale" content="en_US" />
202
+ <meta name="twitter:card" content="summary_large_image" />
203
+ <meta name="twitter:site" content="@BeforeSemicolon" />
204
+ <meta name="twitter:creator" content="@BeforeSemicolon" />
205
+ <meta name="twitter:title" content="${escapeHTML(title)}" />
206
+ <meta name="twitter:image" content="${escapeHTML(image)}" />
207
+ <meta name="twitter:description" content="${escapeHTML(description)}" />
208
+ <meta name="twitter:image:alt" content="${escapeHTML(title)}" />
209
+ <link rel="apple-touch-icon" sizes="180x180" href="/assets/favicon/apple-touch-icon.png" />
210
+ <link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon/favicon-32x32.png" />
211
+ <link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon/favicon-16x16.png" />
212
+ <link rel="manifest" href="/assets/favicon/site.webmanifest" />
213
+ <link rel="icon" type="image/x-icon" href="/assets/favicon/favicon.ico" />
214
+ <link rel="stylesheet" href="/stylesheets/github-dark.hightlighter.css">
215
+ ${jsonScript(pageJson({ ...props, title, description }))}
216
+ ${jsonScript(breadcrumbJson({ title, path: props.path }))}
217
+ ${
218
+ isDev
219
+ ? ''
220
+ : `<!-- Google tag (gtag.js) -->
221
+ <script async src="https://www.googletagmanager.com/gtag/js?id=G-N3MXGDP5PS"></script>
222
+ <script>
223
+ window.dataLayer = window.dataLayer || [];
224
+ function gtag(){dataLayer.push(arguments);}
225
+ gtag('js', new Date());
226
+
227
+ gtag('config', 'G-N3MXGDP5PS');
228
+ </script>`
229
+ }
230
+ `
231
+ }
@@ -0,0 +1,41 @@
1
+ import logo from './_logo.js'
2
+
3
+ export default (props = {}) => {
4
+ const isDocs = props.path?.startsWith('/documentation')
5
+
6
+ return `
7
+ <header class="site-header">
8
+ <div class="header-inner wrapper">
9
+ <h1>
10
+ <a href="/" aria-label="Markup home">
11
+ ${logo({ fill: 'currentColor', width: '90px' })}
12
+ </a>
13
+ </h1>
14
+ ${
15
+ isDocs
16
+ ? `
17
+ <nav class="nav-actions docs-actions">
18
+ <a href="https://github.com/beforesemicolon/markup" target="_blank" rel="noopener" aria-label="Markup GitHub repository" class="github-link docs-github-link">
19
+ <span>v${props.projectMeta?.version || ''}</span>
20
+ <svg aria-hidden="true" viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path></svg>
21
+ </a>
22
+ </nav>
23
+ `
24
+ : `
25
+ <nav class="nav-links">
26
+ <a href="/#features">Features</a>
27
+ <a href="/#code">Code</a>
28
+ <a href="/#install">Install</a>
29
+ </nav>
30
+ <nav class="nav-actions">
31
+ <a href="https://github.com/beforesemicolon/markup" target="_blank" rel="noopener" aria-label="GitHub" class="github-link">
32
+ <svg aria-hidden="true" viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path></svg>
33
+ </a>
34
+ <a href="/documentation" class="btn-primary">Documentation</a>
35
+ </nav>
36
+ `
37
+ }
38
+ </div>
39
+ </header>
40
+ `
41
+ }
@@ -0,0 +1,31 @@
1
+ export default ({ fill = '#D2ECFF', width = '80px' } = {}) => `
2
+ <svg
3
+ xmlns="http://www.w3.org/2000/svg"
4
+ viewBox="0 0 207.25 61.99"
5
+ width="207.25"
6
+ height="61.99"
7
+ aria-hidden="true"
8
+ style="width: ${width}; height: auto"
9
+ >
10
+ <g fill="${fill}">
11
+ <path
12
+ d="m47.74.19c-.93-.39-2.01-.17-2.72.54l-20.38,20.38L4.27.73C3.55.02,2.48-.2,1.54.19.61.58,0,1.49,0,2.5v46.81h5V8.54l16.11,16.11-9.19,9.19,3.54,3.54,9.19-9.19,9.19,9.19,3.54-3.54-9.19-9.19,16.11-16.11v40.77h5V2.5c0-1.01-.61-1.92-1.54-2.31Z"
13
+ />
14
+ <path
15
+ d="m84.81,19.78v29.53h-4.7v-5.34c-.86,1.84-2.16,3.26-3.9,4.26-1.74,1-3.77,1.5-6.08,1.5-2.62,0-4.92-.63-6.9-1.88-1.98-1.25-3.5-3.02-4.58-5.31-1.08-2.29-1.61-4.96-1.61-8.01s.55-5.74,1.64-8.07c1.1-2.33,2.63-4.14,4.61-5.43,1.98-1.29,4.26-1.94,6.84-1.94,2.31,0,4.32.51,6.05,1.53,1.72,1.02,3.03,2.45,3.93,4.29v-5.11h4.7Zm-7.04,23.04c1.56-1.98,2.35-4.78,2.35-8.42s-.78-6.44-2.35-8.39c-1.57-1.96-3.8-2.94-6.69-2.94s-5.16,1.01-6.78,3.02c-1.62,2.02-2.44,4.82-2.44,8.42s.8,6.38,2.41,8.33c1.6,1.96,3.87,2.94,6.81,2.94s5.13-.99,6.69-2.96Z"
16
+ />
17
+ <path
18
+ d="m110.46,19.43l-.12,4.34c-.9-.31-1.94-.47-3.11-.47-2.86,0-4.98.89-6.37,2.67-1.39,1.78-2.08,3.94-2.08,6.49v16.85h-4.75v-21.25c0-3.05-.16-5.81-.47-8.28h4.52l.47,5.46c.74-2,1.94-3.52,3.58-4.58,1.64-1.06,3.52-1.58,5.63-1.58.98,0,1.88.12,2.7.35Z"
19
+ />
20
+ <path
21
+ d="m135.17,49.31l-15.14-14.21v14.21h-4.75V6.11h4.75v27.24l13.91-13.5h6.05l-14.79,14.15,16.2,15.32h-6.22Z"
22
+ />
23
+ <path
24
+ d="m170.22,19.78v29.53h-4.64v-5.11c-.94,1.8-2.25,3.17-3.93,4.11-1.68.94-3.58,1.41-5.69,1.41-3.48,0-6.12-.98-7.92-2.94-1.8-1.96-2.7-4.85-2.7-8.69v-18.31h4.75v18.2c0,2.66.55,4.62,1.64,5.87,1.09,1.25,2.76,1.88,4.99,1.88,2.62,0,4.73-.85,6.34-2.55,1.6-1.7,2.41-3.94,2.41-6.72v-16.67h4.75Z"
25
+ />
26
+ <path
27
+ d="m200.97,21.02c2,1.29,3.54,3.1,4.64,5.43,1.1,2.33,1.64,5.02,1.64,8.07s-.55,5.72-1.64,8.01c-1.1,2.29-2.63,4.06-4.61,5.31-1.98,1.25-4.28,1.88-6.9,1.88-2.31,0-4.32-.51-6.05-1.53-1.72-1.02-3.03-2.47-3.93-4.34v18.14h-4.75V28.06c0-3.05-.16-5.81-.47-8.28h4.52l.47,5.69c.82-2.03,2.12-3.61,3.9-4.73,1.78-1.12,3.88-1.67,6.31-1.67,2.58,0,4.87.65,6.87,1.94Zm-1.03,21.84c1.58-1.96,2.38-4.73,2.38-8.33s-.8-6.41-2.41-8.42c-1.61-2.02-3.84-3.02-6.69-3.02s-5.19.98-6.75,2.94c-1.57,1.96-2.35,4.75-2.35,8.39s.78,6.45,2.35,8.42c1.57,1.98,3.82,2.96,6.75,2.96s5.14-.98,6.72-2.94Z"
28
+ />
29
+ </g>
30
+ </svg>
31
+ `
@@ -0,0 +1,92 @@
1
+ import meta from './_head-meta.js'
2
+ import header from './_header.js'
3
+ import footer from './_footer.js'
4
+ import copyCode from './_copy-code.js'
5
+
6
+ const githubDocsPath =
7
+ 'https://github.com/beforesemicolon/markup/tree/main/docs'
8
+
9
+ const navCategoryToHTML = (docs, currentPath) =>
10
+ Array.from(docs.entries())
11
+ .map(([k, v]) => {
12
+ if (k.endsWith('.html')) {
13
+ const href = v.path.replace(/(index)?\.html/, '')
14
+
15
+ return `<li ${
16
+ currentPath === v.path ? 'class="active"' : ''
17
+ }><a href="${href}">${v.name}</a></li>`
18
+ }
19
+
20
+ return `<ol><span>${k}</span>${navCategoryToHTML(
21
+ v,
22
+ currentPath
23
+ )}</ol>`
24
+ })
25
+ .join('')
26
+
27
+ export default (props) => {
28
+ const docs = props.siteMap.get('documentation')
29
+ const isDocsIndex = props.path === '/documentation/index.html'
30
+ const docsMenu = `<ul>${navCategoryToHTML(docs, props.path)}</ul>`
31
+ const pages = [...docs.values()].flatMap((page) =>
32
+ page instanceof Map ? [...page.values()] : [page]
33
+ )
34
+
35
+ let nextPage, previousPage
36
+
37
+ for (let i = 0; i < pages.length; i++) {
38
+ if (pages[i].path === props.path) {
39
+ nextPage = pages[i + 1]
40
+ previousPage = pages[i - 1]
41
+ }
42
+ }
43
+
44
+ return `
45
+ <!doctype html>
46
+ <html lang="en">
47
+ <head>
48
+ ${meta(props)}
49
+ <link rel="stylesheet" href="/stylesheets/documentation.css?v=20260621exact">
50
+ </head>
51
+ <body>
52
+ ${header(props)}
53
+
54
+ <div id="mobile-menu-toggle">
55
+ <a href="#docs-nav" role="button" aria-label="toggle mobile menu open"></a>
56
+ </div>
57
+
58
+ <main id="documentation" class="wrapper${isDocsIndex ? ' docs-index' : ''}">
59
+ <nav id="docs-nav">
60
+ ${docsMenu}
61
+ <a href="${props.path}" class="close-mobile-menu" role="button" aria-label="toggle mobile menu close"></a>
62
+ </nav>
63
+ <article>
64
+ ${props.content}
65
+
66
+ <div id="page-navigation">
67
+ ${previousPage ? `<a href="${previousPage.path.replace('.html', '')}" id="prev-doc"><span aria-hidden="true">&lt;&lt;</span> ${previousPage.name}</a>` : ''}
68
+ ${nextPage ? `<a href="${nextPage.path.replace('.html', '')}" id="next-doc">${nextPage.name} <span aria-hidden="true">&gt;&gt;</span></a>` : ''}
69
+ </div>
70
+
71
+ <a href="${`${githubDocsPath}${props.path.replace('.html', '')}.md`}" id="edit-doc">edit this doc</a>
72
+ </article>
73
+ <aside id="table-of-content">
74
+ <h4>Content</h4>
75
+ <ul>
76
+ ${props.tableOfContent
77
+ .map(
78
+ (c) => `<li><a href="${c.path}">${c.label}</a></li>`
79
+ )
80
+ .join('')}
81
+ </ul>
82
+ </aside>
83
+ </main>
84
+
85
+ ${footer()}
86
+
87
+ ${copyCode()}
88
+
89
+ </body>
90
+ </html>
91
+ `
92
+ }