@brillout/docpress 0.1.13 → 0.1.14

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.
@@ -2,54 +2,6 @@ import {
2
2
  assert
3
3
  } from "./chunk-G2A5MZJA.js";
4
4
 
5
- // src/utils/Emoji/Emoji.ts
6
- import React from "react";
7
-
8
- // src/utils/Emoji/mechanical-arm.svg
9
- var mechanical_arm_default = "/assets/mechanical-arm-TR7IQQMG.svg";
10
-
11
- // src/utils/Emoji/compass.svg
12
- var compass_default = "/assets/compass-2RWQU3E4.svg";
13
-
14
- // src/utils/Emoji/road-fork.svg
15
- var road_fork_default = "/assets/road-fork-3WZLW3HB.svg";
16
-
17
- // src/utils/Emoji/shield.svg
18
- var shield_default = "/assets/shield-CU45RG5C.svg";
19
-
20
- // src/utils/Emoji/typescript.svg
21
- var typescript_default = "/assets/typescript-ALIPKLRM.svg";
22
-
23
- // src/utils/Emoji/engine.png
24
- var engine_default = "/assets/engine-6Q6VSCVA.png";
25
-
26
- // src/utils/Emoji/Emoji.ts
27
- function Emoji({ name, style }) {
28
- const emoji = name === "warning" && Unicode(9888, { fontFamily: "emoji" }) || name === "lab" && Unicode(9879) || name === "info" && Unicode(8505, { fontFamily: "emoji" }) || name === "package" && Unicode(128230) || name === "gift" && Unicode(127873) || name === "sparkling-heart" && Unicode(128150) || name === "red-circle" && Unicode(11093) || name === "engine" && Img(engine_default) || name === "typescript" && Img(typescript_default) || name === "shield" && Img(shield_default) || name === "road-fork" && Img(road_fork_default, "1.4em") || name === "writing-hang" && Unicode(9997) || name === "dizzy" && Unicode(128171) || name === "mechanical-arm" && Img(mechanical_arm_default) || name === "rocket" && Unicode(128640) || name === "wrench" && Unicode(128295) || name === "compass" && Img(compass_default, "1.4em") || name === "seedling" && Unicode(127793) || name === "books" && Unicode(128218) || name === "plug" && Unicode(128268) || name === "earth" && Unicode(127757) || name === "gear" && Unicode(9881) || name === "red-heart" && Unicode(10084, { fontFamily: "emoji" }) || name === "high-voltage" && Unicode(9889) || name === "sparkles" && Unicode(10024) || name === "gem-stone" && Unicode(128142) || name === "trophy" && Unicode(127942) || false;
29
- assert(emoji, { name });
30
- return emoji;
31
- function Unicode(codePoint, styleAddendum) {
32
- const text = String.fromCodePoint(codePoint);
33
- if (style || styleAddendum) {
34
- return React.createElement("span", { style: { ...style, ...styleAddendum } }, text);
35
- } else {
36
- return React.createElement(React.Fragment, null, text);
37
- }
38
- }
39
- function Img(imgSrc, width = "1.15em") {
40
- const props = {
41
- src: imgSrc,
42
- style: {
43
- verticalAlign: "text-top",
44
- fontSize: "1em",
45
- width,
46
- ...style
47
- }
48
- };
49
- return React.createElement("img", props);
50
- }
51
- }
52
-
53
5
  // src/utils/filter.ts
54
6
  function filter(obj, predicate) {
55
7
  const result = {};
@@ -142,13 +94,61 @@ async function crawlAllFiles(dir) {
142
94
  return allFiles.flat().map(toPosixPath);
143
95
  }
144
96
 
97
+ // src/utils/Emoji/Emoji.ts
98
+ import React from "react";
99
+
100
+ // src/utils/Emoji/mechanical-arm.svg
101
+ var mechanical_arm_default = "/assets/mechanical-arm-TR7IQQMG.svg";
102
+
103
+ // src/utils/Emoji/compass.svg
104
+ var compass_default = "/assets/compass-2RWQU3E4.svg";
105
+
106
+ // src/utils/Emoji/road-fork.svg
107
+ var road_fork_default = "/assets/road-fork-3WZLW3HB.svg";
108
+
109
+ // src/utils/Emoji/shield.svg
110
+ var shield_default = "/assets/shield-CU45RG5C.svg";
111
+
112
+ // src/utils/Emoji/typescript.svg
113
+ var typescript_default = "/assets/typescript-ALIPKLRM.svg";
114
+
115
+ // src/utils/Emoji/engine.png
116
+ var engine_default = "/assets/engine-6Q6VSCVA.png";
117
+
118
+ // src/utils/Emoji/Emoji.ts
119
+ function Emoji({ name, style }) {
120
+ const emoji = name === "warning" && Unicode(9888, { fontFamily: "emoji" }) || name === "lab" && Unicode(9879) || name === "info" && Unicode(8505, { fontFamily: "emoji" }) || name === "package" && Unicode(128230) || name === "gift" && Unicode(127873) || name === "sparkling-heart" && Unicode(128150) || name === "red-circle" && Unicode(11093) || name === "engine" && Img(engine_default) || name === "typescript" && Img(typescript_default) || name === "shield" && Img(shield_default) || name === "road-fork" && Img(road_fork_default, "1.4em") || name === "writing-hang" && Unicode(9997) || name === "dizzy" && Unicode(128171) || name === "mechanical-arm" && Img(mechanical_arm_default) || name === "rocket" && Unicode(128640) || name === "wrench" && Unicode(128295) || name === "compass" && Img(compass_default, "1.4em") || name === "seedling" && Unicode(127793) || name === "books" && Unicode(128218) || name === "plug" && Unicode(128268) || name === "earth" && Unicode(127757) || name === "gear" && Unicode(9881) || name === "red-heart" && Unicode(10084, { fontFamily: "emoji" }) || name === "high-voltage" && Unicode(9889) || name === "sparkles" && Unicode(10024) || name === "gem-stone" && Unicode(128142) || name === "trophy" && Unicode(127942) || false;
121
+ assert(emoji, { name });
122
+ return emoji;
123
+ function Unicode(codePoint, styleAddendum) {
124
+ const text = String.fromCodePoint(codePoint);
125
+ if (style || styleAddendum) {
126
+ return React.createElement("span", { style: { ...style, ...styleAddendum } }, text);
127
+ } else {
128
+ return React.createElement(React.Fragment, null, text);
129
+ }
130
+ }
131
+ function Img(imgSrc, width = "1.15em") {
132
+ const props = {
133
+ src: imgSrc,
134
+ style: {
135
+ verticalAlign: "text-top",
136
+ fontSize: "1em",
137
+ width,
138
+ ...style
139
+ }
140
+ };
141
+ return React.createElement("img", props);
142
+ }
143
+ }
144
+
145
145
  export {
146
- Emoji,
147
146
  filter,
148
147
  determineSectionUrlHash,
149
148
  determineSectionTitle,
150
149
  jsxToTextContent,
151
150
  objectAssign,
152
- crawlAllFiles
151
+ crawlAllFiles,
152
+ Emoji
153
153
  };
154
- //# sourceMappingURL=chunk-P6M6A4HU.js.map
154
+ //# sourceMappingURL=chunk-7HKDCMSZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/filter.ts","../src/utils/determineSectionUrlHash.ts","../src/utils/jsxToTextContent.ts","../src/utils/objectAssign.ts","../src/utils/crawlAllFiles.ts","../src/utils/filesystemPathHandling.ts","../src/utils/Emoji/Emoji.ts"],"sourcesContent":["export { filter }\n\n// https://stackoverflow.com/questions/66341757/typescript-how-to-filter-the-object\nfunction filter<T extends object>(obj: T, predicate: <K extends keyof T>(value: T[K], key: K) => boolean): T {\n const result: { [K in keyof T]?: T[K] } = {}\n ;(Object.keys(obj) as Array<keyof T>).forEach((name) => {\n if (predicate(obj[name], name)) {\n result[name] = obj[name]\n }\n })\n return result as T\n}\n","import { assert } from './assert'\n\nexport { determineSectionUrlHash }\nexport { determineSectionTitle }\n\nfunction determineSectionUrlHash(title: string): string {\n const urlHash = title\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter(Boolean)\n .join('-')\n return urlHash\n}\n\nfunction determineSectionTitle(urlWithHash: string, titleNormalCase: boolean): string {\n assert(urlWithHash.includes('#'), { urlWithHash })\n const urlHash = urlWithHash.split('#')[1]\n const title = urlHash\n .split('-')\n .map((word, i) => {\n if (i === 0) {\n return capitalizeFirstLetter(word)\n }\n if (!titleNormalCase && word.length >= 4) {\n return capitalizeFirstLetter(word)\n }\n return word\n })\n .join(' ')\n return title\n}\n\nfunction capitalizeFirstLetter(word: string): string {\n return word[0].toUpperCase() + word.slice(1)\n}\n","import { assert } from './assert'\n\nexport { jsxToTextContent }\n\n// https://stackoverflow.com/questions/34204975/react-is-there-something-similar-to-node-textcontent/60564620#60564620\nfunction jsxToTextContent(node: JSX.Element | string): string {\n if (['string', 'number'].includes(typeof node)) return String(node)\n if (node instanceof Array) return node.map(jsxToTextContent).join('')\n if (typeof node === 'object' && node) return jsxToTextContent(node.props.children)\n assert(false)\n}\n","export { objectAssign }\n\n// Same as `Object.assign()` but with type inference\nfunction objectAssign<Obj extends Object, ObjAddendum>(\n obj: Obj,\n objAddendum: ObjAddendum\n): asserts obj is Obj & ObjAddendum {\n Object.assign(obj, objAddendum)\n}\n","export { crawlAllFiles }\n\nimport path from 'path'\nimport { promises as fsp } from 'fs'\nimport { toPosixPath } from './filesystemPathHandling'\n\n// Adapted from https://stackoverflow.com/questions/5827612/node-js-fs-readdir-recursive-directory-search/45130990#45130990\nasync function crawlAllFiles(dir: string): Promise<string[]> {\n const dirFiles = await fsp.readdir(dir, { withFileTypes: true })\n const allFiles = await Promise.all(\n dirFiles.map((file) => {\n const filePath = path.resolve(dir, file.name)\n return file.isDirectory() ? crawlAllFiles(filePath) : filePath\n })\n )\n return allFiles.flat().map(toPosixPath)\n}\n","export { toPosixPath }\nexport { assertPosixPath }\nexport { toSystemPath }\n\nimport assert from 'assert'\n\nconst sepPosix = '/'\nconst sepWin32 = '\\\\'\n\nfunction toPosixPath(path: string) {\n if (isPosix()) {\n assertPosixPath(path)\n return path\n }\n if (isWin32()) {\n const pathPosix = path.split(sepWin32).join(sepPosix)\n assertPosixPath(pathPosix)\n return pathPosix\n }\n assert(false)\n}\n\nfunction assertPosixPath(path: string) {\n assert(path && !path.includes(sepWin32), `Wrongly formatted path: ${path}`)\n}\n\nfunction toSystemPath(path: string) {\n if (isPosix()) {\n return toPosixPath(path)\n }\n if (isWin32()) {\n return path.split(sepPosix).join(sepWin32)\n }\n assert(false)\n}\n\nfunction isWin32() {\n return process.platform === 'win32'\n}\nfunction isPosix() {\n return !isWin32()\n}\n","import React from 'react'\nimport { assert } from '../assert'\n\nimport { iconMechanicalArm, iconCompass, iconRoadFork, iconShield, iconTypescript, iconEngine } from './assets'\n\nexport { Emoji }\nexport type { EmojiName }\n\ntype EmojiName =\n | 'warning'\n | 'typescript'\n | 'shield'\n | 'mechanical-arm'\n | 'mountain'\n | 'rocket'\n | 'wrench'\n | 'compass'\n | 'seedling'\n | 'books'\n | 'plug'\n | 'earth'\n | 'gear'\n | 'red-heart'\n | 'high-voltage'\n | 'gem-stone'\n | 'dizzy'\n | 'sparkles'\n | 'writing-hang'\n | 'road-fork'\n | 'engine'\n | 'red-circle'\n | 'sparkling-heart'\n | 'gift'\n | 'package'\n | 'info'\n | 'lab'\n | 'trophy'\n\nfunction Emoji({ name, style }: { name: EmojiName; style?: React.CSSProperties }): JSX.Element {\n const emoji =\n // ***\n // U+26A0\n // https://emojipedia.org/warning/\n // https://www.unicompat.com/26A0 => 94.1%\n // https://www.unicompat.com/26A0-FE0F => 92.4%\n // https://www.unicompat.com/2697 => 94.1%\n (name === 'warning' && Unicode(0x26a0, { fontFamily: 'emoji' })) ||\n // ***\n // U+2697\n // https://emojipedia.org/alembic/\n // https://www.unicompat.com/2697 => 94.1%\n (name === 'lab' && Unicode(0x2697)) ||\n // ***\n // U+2139\n // https://emojipedia.org/information/\n // https://www.unicompat.com/2139 => 94.8%\n // https://www.unicompat.com/2139-FE0F => 92.4%\n (name === 'info' && Unicode(0x2139, { fontFamily: 'emoji' })) ||\n // ***\n // U+1F4E6\n // https://emojipedia.org/package/\n // https://www.unicompat.com/1F4E6 => 94.1%\n (name === 'package' && Unicode(0x1f4e6)) ||\n // ***\n // U+1F381\n // https://emojipedia.org/wrapped-gift/\n // https://www.unicompat.com/1F381 => 94.1%\n (name === 'gift' && Unicode(0x1f381)) ||\n // ***\n // U+1F496\n // https://emojipedia.org/sparkling-heart/\n // https://www.unicompat.com/1F496 => 94.1%\n (name === 'sparkling-heart' && Unicode(0x1f496)) ||\n // ***\n // U+2B55\n // https://emojipedia.org/hollow-red-circle/\n // https://www.unicompat.com/2B55 => 94.1%\n (name === 'red-circle' && Unicode(0x2b55)) ||\n // ***\n (name === 'engine' && Img(iconEngine)) ||\n // ***\n // https://www.typescriptlang.org/branding/\n (name === 'typescript' && Img(iconTypescript)) ||\n // ***\n // U+FE0F\n // https://emojipedia.org/shield/\n // https://www.unicompat.com/FE0F => 46.5%\n // https://icon-sets.iconify.design/noto/shield/\n (name === 'shield' && Img(iconShield)) ||\n // ***\n // Custom\n (name === 'road-fork' && Img(iconRoadFork, '1.4em')) ||\n // ***\n // U+270D\n // https://emojipedia.org/writing-hand/\n // https://www.unicompat.com/270D => 93.8%\n (name === 'writing-hang' && Unicode(0x270d)) ||\n // ***\n // U+1F4AB\n // https://emojipedia.org/dizzy/\n // https://www.unicompat.com/1F4AB => 94.1%\n (name === 'dizzy' && Unicode(0x1f4ab)) ||\n // ***\n // U+1F9BE\n // https://iconify.design/icon-sets/noto/mechanical-arm.html\n // https://emojipedia.org/mechanical-arm/\n // https://www.unicompat.com/1f9be => 65.5%\n (name === 'mechanical-arm' && Img(iconMechanicalArm)) ||\n // ***\n // U+1F680\n // https://www.unicompat.com/1F680 => 94.1\n (name === 'rocket' && Unicode(0x1f680)) ||\n // ***\n // U+1F527\n // https://emojipedia.org/wrench/\n // https://www.unicompat.com/1F527 => 94.1%\n (name === 'wrench' && Unicode(0x1f527)) ||\n // ***\n // U+1F9ED\n // https://iconify.design/icon-sets/noto/compass.html\n // https://www.unicompat.com/1F9ED => 67.1%\n (name === 'compass' && Img(iconCompass, '1.4em')) ||\n // ***\n // U+1F331\n // https://www.unicompat.com/1F331 => 94.1%\n (name === 'seedling' && Unicode(0x1f331)) ||\n // ***\n // U+1F4DA\n // https://www.unicompat.com/1F4DA => 94.1%\n (name === 'books' && Unicode(0x1f4da)) ||\n // ***\n // U+1F50C\n // https://www.unicompat.com/1F50C => 94.1%\n (name === 'plug' && Unicode(0x1f50c)) ||\n // ***\n // U+1F30D\n // https://www.unicompat.com/1F30D => 88.8%\n (name === 'earth' && Unicode(0x1f30d)) ||\n // ***\n // U+2699\n // https://www.unicompat.com/2699 => 94.1%\n (name === 'gear' && Unicode(0x2699)) ||\n // ***\n // U+2764\n // https://emojipedia.org/red-heart/\n // https://www.unicompat.com/2764 => 94.4%\n // https://www.unicompat.com/2764-FE0F => 92.4%\n (name === 'red-heart' && Unicode(0x2764, { fontFamily: 'emoji' })) ||\n // U+26A1\n // https://www.unicompat.com/26A1 => 94.1%\n (name === 'high-voltage' && Unicode(0x26a1)) ||\n // U+2728\n // https://emojipedia.org/sparkles/\n // https://www.unicompat.com/2728 => 94.1%\n (name === 'sparkles' && Unicode(0x2728)) ||\n // ***\n // U+1F48E\n // https://emojipedia.org/gem-stone/\n // https://www.unicompat.com/1F48E => 94.1%\n (name === 'gem-stone' && Unicode(0x1f48e)) ||\n // ***\n // 0x1F3C6\n // https://emojipedia.org/trophy/\n // https://www.unicompat.com/1F3C6 => 94.1%\n (name === 'trophy' && Unicode(0x1f3c6)) ||\n false\n /* ======= Unused ========\n // ***\n // U+1FAA8\n // https://emojipedia.org/rock/\n // https://www.unicompat.com/1faa8 => 20.7%\n //\n // ***\n // U+26F0\n // https://emojipedia.org/mountain/\n // https://iconify.design/icon-sets/noto/mountain.html\n // https://www.unicompat.com/26F0 => 89.3%\n (name === 'mountain' && Img(iconMountain)) ||\n //\n // ***\n // U+2194\n // https://emojipedia.org/left-right-arrow/\n // https://www.unicompat.com/2194 => 95.0%\n // Couldn't manage to show colored version\n (name === 'left-right-arrow' && Unicode(0x2194)) ||\n (name === 'left-right-arrow' && Unicode(0x2194, { fontFamily: 'reset' })) ||\n (name === 'left-right-arrow' && Unicode(0xFE0F)) ||\n (name === 'left-right-arrow' && Unicode(0xFE0F, { fontFamily: 'reset' })) ||\n ======================== */\n\n assert(emoji, { name })\n\n return emoji\n\n function Unicode(codePoint: number, styleAddendum?: React.CSSProperties) {\n const text = String.fromCodePoint(codePoint)\n if (style || styleAddendum) {\n return React.createElement('span', { style: { ...style, ...styleAddendum } }, text)\n } else {\n return React.createElement(React.Fragment, null, text)\n }\n }\n\n function Img(imgSrc: string, width: string = '1.15em') {\n const props = {\n src: imgSrc,\n style: {\n verticalAlign: 'text-top',\n fontSize: '1em',\n width,\n ...style\n }\n }\n return React.createElement('img', props)\n }\n}\n"],"mappings":"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","names":["assert","path","assert"]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  determineSectionUrlHash
3
- } from "./chunk-P6M6A4HU.js";
3
+ } from "./chunk-7HKDCMSZ.js";
4
4
  import {
5
5
  assert
6
6
  } from "./chunk-G2A5MZJA.js";
@@ -125,13 +125,11 @@ var config = {
125
125
  },
126
126
  extensions: [{
127
127
  npmPackageName: "@brillout/docpress",
128
- pageFiles: [
128
+ pageFilesDist: [
129
129
  "@brillout/docpress/renderer/_default.page.server.js",
130
- "@brillout/docpress/renderer/_default.page.server.css",
131
- "@brillout/docpress/renderer/_default.page.client.js",
132
- "@brillout/docpress/renderer/_default.page.client.css"
130
+ "@brillout/docpress/renderer/_default.page.client.js"
133
131
  ],
134
- assetsDir: "dist/"
132
+ assetsDir: "/dist/"
135
133
  }],
136
134
  includeAssetsImportedByServer: true,
137
135
  disableAutoFullBuild: true
@@ -148,4 +146,4 @@ var vite_config_default = config;
148
146
  export {
149
147
  vite_config_default
150
148
  };
151
- //# sourceMappingURL=chunk-V7ZWIKEX.js.map
149
+ //# sourceMappingURL=chunk-GBXQT242.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/vite.config.ts","../src/markdownHeadingsVitePlugin.ts"],"sourcesContent":["import mdx from '@mdx-js/rollup'\nimport react from '@vitejs/plugin-react'\nimport ssr from 'vite-plugin-ssr/plugin'\nimport { UserConfig } from 'vite'\nimport { markdownHeadingsVitePlugin } from './markdownHeadingsVitePlugin'\nimport rehypePrettyCode from 'rehype-pretty-code'\nimport remarkGfm from 'remark-gfm'\n\nconst root = process.cwd()\nconst prettyCode = [rehypePrettyCode, { theme: 'github-light' }]\nconst rehypePlugins: any = [prettyCode]\nconst remarkPlugins = [remarkGfm]\n\nconst config: UserConfig = {\n root,\n plugins: [\n react({\n jsxRuntime: 'classic'\n }),\n markdownHeadingsVitePlugin(),\n mdx({ rehypePlugins, remarkPlugins }),\n ssr({\n prerender: {\n noExtraDir: true\n },\n // @ts-ignore until new version is released\n extensions: [{\n npmPackageName: '@brillout/docpress',\n /*\n pageFilesSrc: '/renderer/*',\n /*/\n pageFilesDist: [\n '@brillout/docpress/renderer/_default.page.server.js',\n '@brillout/docpress/renderer/_default.page.client.js'\n ],\n //*/\n assetsDir: '/dist/'\n }],\n includeAssetsImportedByServer: true,\n disableAutoFullBuild: true\n })\n ],\n // TODO: remove `react`?\n optimizeDeps: { include: ['@mdx-js/react', 'react', 'react-dom'] },\n // @ts-ignore\n ssr: {\n noExternal: ['@brillout/docpress']\n },\n clearScreen: false\n}\n\nexport default config\n","import { assert, determineSectionUrlHash } from '../src/utils/server'\n\nexport { markdownHeadingsVitePlugin }\nexport type { MarkdownHeading }\n\ntype MarkdownHeading = {\n title: string\n id: string\n headingLevel: number\n titleAddendum?: string\n}\n\nfunction markdownHeadingsVitePlugin() {\n return {\n name: 'mdx-headings',\n enforce: 'pre',\n transform: async (code: string, id: string) => {\n if (!id.includes('.page.') || !id.endsWith('.mdx')) {\n return\n }\n const codeNew = transform(code)\n return codeNew\n }\n }\n}\n\nfunction transform(code: string) {\n const headings: MarkdownHeading[] = []\n let isCodeBlock = false\n let codeNew = code\n .split('\\n')\n .map((line) => {\n // Skip code blocks, e.g.\n // ~~~md\n // # Markdown Example\n // Bla\n // ~~~\n if (line.startsWith('~~~') || line.startsWith('```')) {\n isCodeBlock = !isCodeBlock\n return line\n }\n if (isCodeBlock) {\n return line\n }\n\n if (line.startsWith('#')) {\n const { id, headingLevel, title, headingHtml } = parseMarkdownHeading(line)\n headings.push({ id, headingLevel, title })\n return headingHtml\n }\n if (line.startsWith('<h')) {\n assert(false, { line })\n }\n\n return line\n })\n .join('\\n')\n const headingsExportCode = `export const headings = [${headings\n .map((heading) => JSON.stringify(heading))\n .join(', ')}];`\n codeNew += `\\n\\n${headingsExportCode}\\n`\n return codeNew\n}\n\nfunction parseMarkdownHeading(line: string): MarkdownHeading & { headingHtml: string } {\n const [lineBegin, ...lineWords] = line.split(' ')\n assert(lineBegin.split('#').join('') === '', { line, lineWords })\n const headingLevel = lineBegin.length\n\n const titleMdx = lineWords.join(' ')\n assert(!titleMdx.startsWith(' '), { line, lineWords })\n assert(titleMdx, { line, lineWords })\n\n const id = determineSectionUrlHash(titleMdx)\n const title = titleMdx\n\n const headingHtml = `<h${headingLevel} id=\"${id}\">${parseTitle(title)}</h${headingLevel}>`\n\n const heading = { headingLevel, title, id, headingHtml }\n return heading\n}\n\nfunction parseTitle(titleMarkdown: string): string {\n type Part = { nodeType: 'text' | 'code'; content: string }\n const parts: Part[] = []\n let current: Part | undefined\n titleMarkdown.split('').forEach((letter) => {\n if (letter === '`') {\n if (current?.nodeType === 'code') {\n // </code>\n parts.push(current)\n current = undefined\n } else {\n // <code>\n if (current) {\n parts.push(current)\n }\n current = { nodeType: 'code', content: '' }\n }\n } else {\n if (!current) {\n current = { nodeType: 'text', content: '' }\n }\n current.content += letter\n }\n })\n if (current) {\n parts.push(current)\n }\n\n const titleHtml = parts\n .map((part) => {\n if (part.nodeType === 'code') {\n return `<code>${serializeText(part.content)}</code>`\n } else {\n assert(part.nodeType === 'text', { parts })\n return serializeText(part.content)\n }\n })\n .join('')\n\n return titleHtml\n\n function serializeText(text: string) {\n const textEscaped = text.split(\"'\").join(\"\\\\'\")\n return `{'${textEscaped}'}`\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Emoji
3
- } from "./chunk-P6M6A4HU.js";
3
+ } from "./chunk-7HKDCMSZ.js";
4
4
  import {
5
5
  assert
6
6
  } from "./chunk-G2A5MZJA.js";
@@ -168,11 +168,11 @@ function withEmoji(name, title) {
168
168
  }
169
169
 
170
170
  export {
171
- getHeadings,
172
- parseTitle,
173
171
  PageContextProvider,
174
172
  usePageContext,
175
173
  isRepoLink,
176
- RepoLink
174
+ RepoLink,
175
+ getHeadings,
176
+ parseTitle
177
177
  };
178
- //# sourceMappingURL=chunk-M7LTQJLV.js.map
178
+ //# sourceMappingURL=chunk-JS5BGVDK.js.map
package/dist/cli/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  vite_config_default
3
- } from "../chunk-V7ZWIKEX.js";
4
- import "../chunk-P6M6A4HU.js";
3
+ } from "../chunk-GBXQT242.js";
4
+ import "../chunk-7HKDCMSZ.js";
5
5
  import "../chunk-G2A5MZJA.js";
6
6
  import "../chunk-TTLAZ2T2.js";
7
7
 
@@ -16,7 +16,7 @@ Error.stackTraceLimit = Infinity;
16
16
  cli();
17
17
  async function cli() {
18
18
  if (isDev) {
19
- await import("../devServer-6O6KCRPG.js");
19
+ await import("../devServer-CXZI7V2M.js");
20
20
  } else if (isBuild) {
21
21
  await build(vite_config_default);
22
22
  await build({ ...vite_config_default, build: { ssr: true } });
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  vite_config_default
3
- } from "./chunk-V7ZWIKEX.js";
4
- import "./chunk-P6M6A4HU.js";
3
+ } from "./chunk-GBXQT242.js";
4
+ import "./chunk-7HKDCMSZ.js";
5
5
  import "./chunk-G2A5MZJA.js";
6
6
  import "./chunk-TTLAZ2T2.js";
7
7
 
@@ -32,4 +32,4 @@ async function startServer() {
32
32
  app.listen(port);
33
33
  console.log(`Server running at http://localhost:${port}`);
34
34
  }
35
- //# sourceMappingURL=devServer-6O6KCRPG.js.map
35
+ //# sourceMappingURL=devServer-CXZI7V2M.js.map
package/dist/index.d.ts CHANGED
@@ -1,65 +1,6 @@
1
1
  import React$1 from 'react';
2
2
  export { FeatureList } from './components/features/FeatureList.js';
3
3
 
4
- declare type EmojiName = 'warning' | 'typescript' | 'shield' | 'mechanical-arm' | 'mountain' | 'rocket' | 'wrench' | 'compass' | 'seedling' | 'books' | 'plug' | 'earth' | 'gear' | 'red-heart' | 'high-voltage' | 'gem-stone' | 'dizzy' | 'sparkles' | 'writing-hang' | 'road-fork' | 'engine' | 'red-circle' | 'sparkling-heart' | 'gift' | 'package' | 'info' | 'lab' | 'trophy';
5
- declare function Emoji({ name, style }: {
6
- name: EmojiName;
7
- style?: React$1.CSSProperties;
8
- }): JSX.Element;
9
-
10
- declare function Link(props: {
11
- href: string;
12
- text?: string | JSX.Element;
13
- noBreadcrumb?: true;
14
- doNotInferSectionTitle?: true;
15
- }): JSX.Element;
16
-
17
- declare function DocLink({ href, text, noBreadcrumb, doNotInferSectionTitle }: {
18
- href: string;
19
- text?: string | JSX.Element;
20
- noBreadcrumb?: true;
21
- doNotInferSectionTitle?: true;
22
- }): JSX.Element;
23
-
24
- declare function isRepoLink(href: string): boolean;
25
- declare function RepoLink({ path, text, editMode }: {
26
- path: string;
27
- text?: string | JSX.Element;
28
- editMode?: true;
29
- }): JSX.Element;
30
-
31
- declare function P(props: React$1.HTMLProps<HTMLDivElement>): JSX.Element;
32
-
33
- declare function Info({ children }: {
34
- children: React$1.ReactNode;
35
- }): JSX.Element;
36
-
37
- declare function ReadingRecommendation({ tour, links }: {
38
- tour?: true;
39
- links: string[];
40
- }): JSX.Element;
41
-
42
- declare function Note({ type, icon, children }: {
43
- icon: JSX.Element | string;
44
- type?: 'error' | 'warning';
45
- children: JSX.Element;
46
- }): JSX.Element;
47
-
48
- declare function ImportMeta({ prop }: {
49
- prop: string;
50
- }): JSX.Element;
51
-
52
- declare function HorizontalLine({ primary }: {
53
- primary?: true;
54
- }): JSX.Element;
55
-
56
- declare function Sponsors(): JSX.Element;
57
-
58
- declare function CodeBlock({ children, lineBreak }: {
59
- children: any;
60
- lineBreak?: true;
61
- }): JSX.Element;
62
-
63
4
  declare function assert(condition: unknown, debugInfo?: unknown): asserts condition;
64
5
  declare function assertUsage(condition: unknown, msg: string): asserts condition;
65
6
 
@@ -76,6 +17,12 @@ declare function objectAssign<Obj extends Object, ObjAddendum>(obj: Obj, objAdde
76
17
 
77
18
  declare function crawlAllFiles(dir: string): Promise<string[]>;
78
19
 
20
+ declare type EmojiName = 'warning' | 'typescript' | 'shield' | 'mechanical-arm' | 'mountain' | 'rocket' | 'wrench' | 'compass' | 'seedling' | 'books' | 'plug' | 'earth' | 'gear' | 'red-heart' | 'high-voltage' | 'gem-stone' | 'dizzy' | 'sparkles' | 'writing-hang' | 'road-fork' | 'engine' | 'red-circle' | 'sparkling-heart' | 'gift' | 'package' | 'info' | 'lab' | 'trophy';
21
+ declare function Emoji({ name, style }: {
22
+ name: EmojiName;
23
+ style?: React$1.CSSProperties;
24
+ }): JSX.Element;
25
+
79
26
  declare type HeadingWithoutLink = {
80
27
  url: string;
81
28
  title: string | JSX.Element;
@@ -134,4 +81,57 @@ declare type Config = {
134
81
  twitterHandle: string;
135
82
  };
136
83
 
84
+ declare function Link(props: {
85
+ href: string;
86
+ text?: string | JSX.Element;
87
+ noBreadcrumb?: true;
88
+ doNotInferSectionTitle?: true;
89
+ }): JSX.Element;
90
+
91
+ declare function DocLink({ href, text, noBreadcrumb, doNotInferSectionTitle }: {
92
+ href: string;
93
+ text?: string | JSX.Element;
94
+ noBreadcrumb?: true;
95
+ doNotInferSectionTitle?: true;
96
+ }): JSX.Element;
97
+
98
+ declare function isRepoLink(href: string): boolean;
99
+ declare function RepoLink({ path, text, editMode }: {
100
+ path: string;
101
+ text?: string | JSX.Element;
102
+ editMode?: true;
103
+ }): JSX.Element;
104
+
105
+ declare function P(props: React$1.HTMLProps<HTMLDivElement>): JSX.Element;
106
+
107
+ declare function Info({ children }: {
108
+ children: React$1.ReactNode;
109
+ }): JSX.Element;
110
+
111
+ declare function ReadingRecommendation({ tour, links }: {
112
+ tour?: true;
113
+ links: string[];
114
+ }): JSX.Element;
115
+
116
+ declare function Note({ type, icon, children }: {
117
+ icon: JSX.Element | string;
118
+ type?: 'error' | 'warning';
119
+ children: JSX.Element;
120
+ }): JSX.Element;
121
+
122
+ declare function ImportMeta({ prop }: {
123
+ prop: string;
124
+ }): JSX.Element;
125
+
126
+ declare function HorizontalLine({ primary }: {
127
+ primary?: true;
128
+ }): JSX.Element;
129
+
130
+ declare function Sponsors(): JSX.Element;
131
+
132
+ declare function CodeBlock({ children, lineBreak }: {
133
+ children: any;
134
+ lineBreak?: true;
135
+ }): JSX.Element;
136
+
137
137
  export { CodeBlock, Config, DocLink, Emoji, EmojiName, HeadingDefinition, HeadingWithoutLink, HorizontalLine, ImportMeta, Info, Link, Note, P, ReadingRecommendation, RepoLink, Sponsors, assert, assertUsage, crawlAllFiles, determineSectionTitle, determineSectionUrlHash, filter, isBrowser, isRepoLink, jsxToTextContent, objectAssign };
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  isRepoLink,
5
5
  parseTitle,
6
6
  usePageContext
7
- } from "./chunk-M7LTQJLV.js";
7
+ } from "./chunk-JS5BGVDK.js";
8
8
  import {
9
9
  FeatureList
10
10
  } from "./chunk-OEVBWUR6.js";
@@ -16,7 +16,7 @@ import {
16
16
  filter,
17
17
  jsxToTextContent,
18
18
  objectAssign
19
- } from "./chunk-P6M6A4HU.js";
19
+ } from "./chunk-7HKDCMSZ.js";
20
20
  import {
21
21
  assert,
22
22
  assertUsage,
@@ -4,12 +4,12 @@ import {
4
4
  getHeadings,
5
5
  parseTitle,
6
6
  usePageContext
7
- } from "../chunk-M7LTQJLV.js";
7
+ } from "../chunk-JS5BGVDK.js";
8
8
  import {
9
9
  Emoji,
10
10
  jsxToTextContent,
11
11
  objectAssign
12
- } from "../chunk-P6M6A4HU.js";
12
+ } from "../chunk-7HKDCMSZ.js";
13
13
  import {
14
14
  assert,
15
15
  assertUsage
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@brillout/docpress",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
4
4
  "exports": {
5
- ".": "./dist/index.js",
6
5
  "./renderer/_default.page.server.js": "./dist/renderer/_default.page.server.js",
7
6
  "./renderer/_default.page.client.js": "./dist/renderer/_default.page.client.js",
8
7
  "./renderer/_default.page.server.css": "./dist/renderer/_default.page.server.css",
9
8
  "./renderer/_default.page.client.css": "./dist/renderer/_default.page.client.css",
9
+ ".": "./dist/index.js",
10
10
  "./features/FeatureList": "./dist/components/features/FeatureList.js",
11
11
  "./features/FeatureList.css": {
12
12
  "browser": "./dist/components/features/FeatureList.css"
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/Emoji/Emoji.ts","../src/utils/filter.ts","../src/utils/determineSectionUrlHash.ts","../src/utils/jsxToTextContent.ts","../src/utils/objectAssign.ts","../src/utils/crawlAllFiles.ts","../src/utils/filesystemPathHandling.ts"],"sourcesContent":["import React from 'react'\nimport { assert } from '../assert'\n\nimport { iconMechanicalArm, iconCompass, iconRoadFork, iconShield, iconTypescript, iconEngine } from './assets'\n\nexport { Emoji }\nexport type { EmojiName }\n\ntype EmojiName =\n | 'warning'\n | 'typescript'\n | 'shield'\n | 'mechanical-arm'\n | 'mountain'\n | 'rocket'\n | 'wrench'\n | 'compass'\n | 'seedling'\n | 'books'\n | 'plug'\n | 'earth'\n | 'gear'\n | 'red-heart'\n | 'high-voltage'\n | 'gem-stone'\n | 'dizzy'\n | 'sparkles'\n | 'writing-hang'\n | 'road-fork'\n | 'engine'\n | 'red-circle'\n | 'sparkling-heart'\n | 'gift'\n | 'package'\n | 'info'\n | 'lab'\n | 'trophy'\n\nfunction Emoji({ name, style }: { name: EmojiName; style?: React.CSSProperties }): JSX.Element {\n const emoji =\n // ***\n // U+26A0\n // https://emojipedia.org/warning/\n // https://www.unicompat.com/26A0 => 94.1%\n // https://www.unicompat.com/26A0-FE0F => 92.4%\n // https://www.unicompat.com/2697 => 94.1%\n (name === 'warning' && Unicode(0x26a0, { fontFamily: 'emoji' })) ||\n // ***\n // U+2697\n // https://emojipedia.org/alembic/\n // https://www.unicompat.com/2697 => 94.1%\n (name === 'lab' && Unicode(0x2697)) ||\n // ***\n // U+2139\n // https://emojipedia.org/information/\n // https://www.unicompat.com/2139 => 94.8%\n // https://www.unicompat.com/2139-FE0F => 92.4%\n (name === 'info' && Unicode(0x2139, { fontFamily: 'emoji' })) ||\n // ***\n // U+1F4E6\n // https://emojipedia.org/package/\n // https://www.unicompat.com/1F4E6 => 94.1%\n (name === 'package' && Unicode(0x1f4e6)) ||\n // ***\n // U+1F381\n // https://emojipedia.org/wrapped-gift/\n // https://www.unicompat.com/1F381 => 94.1%\n (name === 'gift' && Unicode(0x1f381)) ||\n // ***\n // U+1F496\n // https://emojipedia.org/sparkling-heart/\n // https://www.unicompat.com/1F496 => 94.1%\n (name === 'sparkling-heart' && Unicode(0x1f496)) ||\n // ***\n // U+2B55\n // https://emojipedia.org/hollow-red-circle/\n // https://www.unicompat.com/2B55 => 94.1%\n (name === 'red-circle' && Unicode(0x2b55)) ||\n // ***\n (name === 'engine' && Img(iconEngine)) ||\n // ***\n // https://www.typescriptlang.org/branding/\n (name === 'typescript' && Img(iconTypescript)) ||\n // ***\n // U+FE0F\n // https://emojipedia.org/shield/\n // https://www.unicompat.com/FE0F => 46.5%\n // https://icon-sets.iconify.design/noto/shield/\n (name === 'shield' && Img(iconShield)) ||\n // ***\n // Custom\n (name === 'road-fork' && Img(iconRoadFork, '1.4em')) ||\n // ***\n // U+270D\n // https://emojipedia.org/writing-hand/\n // https://www.unicompat.com/270D => 93.8%\n (name === 'writing-hang' && Unicode(0x270d)) ||\n // ***\n // U+1F4AB\n // https://emojipedia.org/dizzy/\n // https://www.unicompat.com/1F4AB => 94.1%\n (name === 'dizzy' && Unicode(0x1f4ab)) ||\n // ***\n // U+1F9BE\n // https://iconify.design/icon-sets/noto/mechanical-arm.html\n // https://emojipedia.org/mechanical-arm/\n // https://www.unicompat.com/1f9be => 65.5%\n (name === 'mechanical-arm' && Img(iconMechanicalArm)) ||\n // ***\n // U+1F680\n // https://www.unicompat.com/1F680 => 94.1\n (name === 'rocket' && Unicode(0x1f680)) ||\n // ***\n // U+1F527\n // https://emojipedia.org/wrench/\n // https://www.unicompat.com/1F527 => 94.1%\n (name === 'wrench' && Unicode(0x1f527)) ||\n // ***\n // U+1F9ED\n // https://iconify.design/icon-sets/noto/compass.html\n // https://www.unicompat.com/1F9ED => 67.1%\n (name === 'compass' && Img(iconCompass, '1.4em')) ||\n // ***\n // U+1F331\n // https://www.unicompat.com/1F331 => 94.1%\n (name === 'seedling' && Unicode(0x1f331)) ||\n // ***\n // U+1F4DA\n // https://www.unicompat.com/1F4DA => 94.1%\n (name === 'books' && Unicode(0x1f4da)) ||\n // ***\n // U+1F50C\n // https://www.unicompat.com/1F50C => 94.1%\n (name === 'plug' && Unicode(0x1f50c)) ||\n // ***\n // U+1F30D\n // https://www.unicompat.com/1F30D => 88.8%\n (name === 'earth' && Unicode(0x1f30d)) ||\n // ***\n // U+2699\n // https://www.unicompat.com/2699 => 94.1%\n (name === 'gear' && Unicode(0x2699)) ||\n // ***\n // U+2764\n // https://emojipedia.org/red-heart/\n // https://www.unicompat.com/2764 => 94.4%\n // https://www.unicompat.com/2764-FE0F => 92.4%\n (name === 'red-heart' && Unicode(0x2764, { fontFamily: 'emoji' })) ||\n // U+26A1\n // https://www.unicompat.com/26A1 => 94.1%\n (name === 'high-voltage' && Unicode(0x26a1)) ||\n // U+2728\n // https://emojipedia.org/sparkles/\n // https://www.unicompat.com/2728 => 94.1%\n (name === 'sparkles' && Unicode(0x2728)) ||\n // ***\n // U+1F48E\n // https://emojipedia.org/gem-stone/\n // https://www.unicompat.com/1F48E => 94.1%\n (name === 'gem-stone' && Unicode(0x1f48e)) ||\n // ***\n // 0x1F3C6\n // https://emojipedia.org/trophy/\n // https://www.unicompat.com/1F3C6 => 94.1%\n (name === 'trophy' && Unicode(0x1f3c6)) ||\n false\n /* ======= Unused ========\n // ***\n // U+1FAA8\n // https://emojipedia.org/rock/\n // https://www.unicompat.com/1faa8 => 20.7%\n //\n // ***\n // U+26F0\n // https://emojipedia.org/mountain/\n // https://iconify.design/icon-sets/noto/mountain.html\n // https://www.unicompat.com/26F0 => 89.3%\n (name === 'mountain' && Img(iconMountain)) ||\n //\n // ***\n // U+2194\n // https://emojipedia.org/left-right-arrow/\n // https://www.unicompat.com/2194 => 95.0%\n // Couldn't manage to show colored version\n (name === 'left-right-arrow' && Unicode(0x2194)) ||\n (name === 'left-right-arrow' && Unicode(0x2194, { fontFamily: 'reset' })) ||\n (name === 'left-right-arrow' && Unicode(0xFE0F)) ||\n (name === 'left-right-arrow' && Unicode(0xFE0F, { fontFamily: 'reset' })) ||\n ======================== */\n\n assert(emoji, { name })\n\n return emoji\n\n function Unicode(codePoint: number, styleAddendum?: React.CSSProperties) {\n const text = String.fromCodePoint(codePoint)\n if (style || styleAddendum) {\n return React.createElement('span', { style: { ...style, ...styleAddendum } }, text)\n } else {\n return React.createElement(React.Fragment, null, text)\n }\n }\n\n function Img(imgSrc: string, width: string = '1.15em') {\n const props = {\n src: imgSrc,\n style: {\n verticalAlign: 'text-top',\n fontSize: '1em',\n width,\n ...style\n }\n }\n return React.createElement('img', props)\n }\n}\n","export { filter }\n\n// https://stackoverflow.com/questions/66341757/typescript-how-to-filter-the-object\nfunction filter<T extends object>(obj: T, predicate: <K extends keyof T>(value: T[K], key: K) => boolean): T {\n const result: { [K in keyof T]?: T[K] } = {}\n ;(Object.keys(obj) as Array<keyof T>).forEach((name) => {\n if (predicate(obj[name], name)) {\n result[name] = obj[name]\n }\n })\n return result as T\n}\n","import { assert } from './assert'\n\nexport { determineSectionUrlHash }\nexport { determineSectionTitle }\n\nfunction determineSectionUrlHash(title: string): string {\n const urlHash = title\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter(Boolean)\n .join('-')\n return urlHash\n}\n\nfunction determineSectionTitle(urlWithHash: string, titleNormalCase: boolean): string {\n assert(urlWithHash.includes('#'), { urlWithHash })\n const urlHash = urlWithHash.split('#')[1]\n const title = urlHash\n .split('-')\n .map((word, i) => {\n if (i === 0) {\n return capitalizeFirstLetter(word)\n }\n if (!titleNormalCase && word.length >= 4) {\n return capitalizeFirstLetter(word)\n }\n return word\n })\n .join(' ')\n return title\n}\n\nfunction capitalizeFirstLetter(word: string): string {\n return word[0].toUpperCase() + word.slice(1)\n}\n","import { assert } from './assert'\n\nexport { jsxToTextContent }\n\n// https://stackoverflow.com/questions/34204975/react-is-there-something-similar-to-node-textcontent/60564620#60564620\nfunction jsxToTextContent(node: JSX.Element | string): string {\n if (['string', 'number'].includes(typeof node)) return String(node)\n if (node instanceof Array) return node.map(jsxToTextContent).join('')\n if (typeof node === 'object' && node) return jsxToTextContent(node.props.children)\n assert(false)\n}\n","export { objectAssign }\n\n// Same as `Object.assign()` but with type inference\nfunction objectAssign<Obj extends Object, ObjAddendum>(\n obj: Obj,\n objAddendum: ObjAddendum\n): asserts obj is Obj & ObjAddendum {\n Object.assign(obj, objAddendum)\n}\n","export { crawlAllFiles }\n\nimport path from 'path'\nimport { promises as fsp } from 'fs'\nimport { toPosixPath } from './filesystemPathHandling'\n\n// Adapted from https://stackoverflow.com/questions/5827612/node-js-fs-readdir-recursive-directory-search/45130990#45130990\nasync function crawlAllFiles(dir: string): Promise<string[]> {\n const dirFiles = await fsp.readdir(dir, { withFileTypes: true })\n const allFiles = await Promise.all(\n dirFiles.map((file) => {\n const filePath = path.resolve(dir, file.name)\n return file.isDirectory() ? crawlAllFiles(filePath) : filePath\n })\n )\n return allFiles.flat().map(toPosixPath)\n}\n","export { toPosixPath }\nexport { assertPosixPath }\nexport { toSystemPath }\n\nimport assert from 'assert'\n\nconst sepPosix = '/'\nconst sepWin32 = '\\\\'\n\nfunction toPosixPath(path: string) {\n if (isPosix()) {\n assertPosixPath(path)\n return path\n }\n if (isWin32()) {\n const pathPosix = path.split(sepWin32).join(sepPosix)\n assertPosixPath(pathPosix)\n return pathPosix\n }\n assert(false)\n}\n\nfunction assertPosixPath(path: string) {\n assert(path && !path.includes(sepWin32), `Wrongly formatted path: ${path}`)\n}\n\nfunction toSystemPath(path: string) {\n if (isPosix()) {\n return toPosixPath(path)\n }\n if (isWin32()) {\n return path.split(sepPosix).join(sepWin32)\n }\n assert(false)\n}\n\nfunction isWin32() {\n return process.platform === 'win32'\n}\nfunction isPosix() {\n return !isWin32()\n}\n"],"mappings":"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","names":["assert","path","assert"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/vite.config.ts","../src/markdownHeadingsVitePlugin.ts"],"sourcesContent":["import mdx from '@mdx-js/rollup'\nimport react from '@vitejs/plugin-react'\nimport ssr from 'vite-plugin-ssr/plugin'\nimport { UserConfig } from 'vite'\nimport { markdownHeadingsVitePlugin } from './markdownHeadingsVitePlugin'\nimport rehypePrettyCode from 'rehype-pretty-code'\nimport remarkGfm from 'remark-gfm'\n\nconst root = process.cwd()\nconst prettyCode = [rehypePrettyCode, { theme: 'github-light' }]\nconst rehypePlugins: any = [prettyCode]\nconst remarkPlugins = [remarkGfm]\n\nconst config: UserConfig = {\n root,\n plugins: [\n react({\n jsxRuntime: 'classic'\n }),\n markdownHeadingsVitePlugin(),\n mdx({ rehypePlugins, remarkPlugins }),\n ssr({\n prerender: {\n noExtraDir: true\n },\n // @ts-ignore until new version is released\n extensions: [{\n npmPackageName: '@brillout/docpress',\n pageFiles: [\n '@brillout/docpress/renderer/_default.page.server.js',\n '@brillout/docpress/renderer/_default.page.server.css',\n '@brillout/docpress/renderer/_default.page.client.js',\n '@brillout/docpress/renderer/_default.page.client.css'\n ],\n assetsDir: 'dist/'\n }],\n includeAssetsImportedByServer: true,\n disableAutoFullBuild: true\n })\n ],\n // TODO: remove `react`?\n optimizeDeps: { include: ['@mdx-js/react', 'react', 'react-dom'] },\n // @ts-ignore\n ssr: {\n noExternal: ['@brillout/docpress']\n },\n clearScreen: false\n}\n\nexport default config\n","import { assert, determineSectionUrlHash } from '../src/utils/server'\n\nexport { markdownHeadingsVitePlugin }\nexport type { MarkdownHeading }\n\ntype MarkdownHeading = {\n title: string\n id: string\n headingLevel: number\n titleAddendum?: string\n}\n\nfunction markdownHeadingsVitePlugin() {\n return {\n name: 'mdx-headings',\n enforce: 'pre',\n transform: async (code: string, id: string) => {\n if (!id.includes('.page.') || !id.endsWith('.mdx')) {\n return\n }\n const codeNew = transform(code)\n return codeNew\n }\n }\n}\n\nfunction transform(code: string) {\n const headings: MarkdownHeading[] = []\n let isCodeBlock = false\n let codeNew = code\n .split('\\n')\n .map((line) => {\n // Skip code blocks, e.g.\n // ~~~md\n // # Markdown Example\n // Bla\n // ~~~\n if (line.startsWith('~~~') || line.startsWith('```')) {\n isCodeBlock = !isCodeBlock\n return line\n }\n if (isCodeBlock) {\n return line\n }\n\n if (line.startsWith('#')) {\n const { id, headingLevel, title, headingHtml } = parseMarkdownHeading(line)\n headings.push({ id, headingLevel, title })\n return headingHtml\n }\n if (line.startsWith('<h')) {\n assert(false, { line })\n }\n\n return line\n })\n .join('\\n')\n const headingsExportCode = `export const headings = [${headings\n .map((heading) => JSON.stringify(heading))\n .join(', ')}];`\n codeNew += `\\n\\n${headingsExportCode}\\n`\n return codeNew\n}\n\nfunction parseMarkdownHeading(line: string): MarkdownHeading & { headingHtml: string } {\n const [lineBegin, ...lineWords] = line.split(' ')\n assert(lineBegin.split('#').join('') === '', { line, lineWords })\n const headingLevel = lineBegin.length\n\n const titleMdx = lineWords.join(' ')\n assert(!titleMdx.startsWith(' '), { line, lineWords })\n assert(titleMdx, { line, lineWords })\n\n const id = determineSectionUrlHash(titleMdx)\n const title = titleMdx\n\n const headingHtml = `<h${headingLevel} id=\"${id}\">${parseTitle(title)}</h${headingLevel}>`\n\n const heading = { headingLevel, title, id, headingHtml }\n return heading\n}\n\nfunction parseTitle(titleMarkdown: string): string {\n type Part = { nodeType: 'text' | 'code'; content: string }\n const parts: Part[] = []\n let current: Part | undefined\n titleMarkdown.split('').forEach((letter) => {\n if (letter === '`') {\n if (current?.nodeType === 'code') {\n // </code>\n parts.push(current)\n current = undefined\n } else {\n // <code>\n if (current) {\n parts.push(current)\n }\n current = { nodeType: 'code', content: '' }\n }\n } else {\n if (!current) {\n current = { nodeType: 'text', content: '' }\n }\n current.content += letter\n }\n })\n if (current) {\n parts.push(current)\n }\n\n const titleHtml = parts\n .map((part) => {\n if (part.nodeType === 'code') {\n return `<code>${serializeText(part.content)}</code>`\n } else {\n assert(part.nodeType === 'text', { parts })\n return serializeText(part.content)\n }\n })\n .join('')\n\n return titleHtml\n\n function serializeText(text: string) {\n const textEscaped = text.split(\"'\").join(\"\\\\'\")\n return `{'${textEscaped}'}`\n }\n}\n"],"mappings":"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","names":[]}