@compiiile/compiiile 2.2.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 (55) hide show
  1. package/.compiiile/public/favicon.png +0 -0
  2. package/.compiiile/src/app.js +5 -0
  3. package/.compiiile/src/components/ClientScript.vue +48 -0
  4. package/.compiiile/src/components/ContentWrapper.vue +288 -0
  5. package/.compiiile/src/components/SlidesContent.vue +56 -0
  6. package/.compiiile/src/components/TableOfContent.vue +65 -0
  7. package/.compiiile/src/components/layout/HamburgerButton.vue +90 -0
  8. package/.compiiile/src/components/layout/TopBar.vue +106 -0
  9. package/.compiiile/src/components/layout/navBar/FilesTree.vue +35 -0
  10. package/.compiiile/src/components/layout/navBar/NavBar.vue +48 -0
  11. package/.compiiile/src/components/layout/navBar/NavListItem.vue +216 -0
  12. package/.compiiile/src/components/searchBar/SearchBar.vue +371 -0
  13. package/.compiiile/src/components/searchBar/SearchResult.vue +98 -0
  14. package/.compiiile/src/env.d.ts +1 -0
  15. package/.compiiile/src/layouts/BaseLayout.astro +38 -0
  16. package/.compiiile/src/layouts/SlidesLayout.astro +12 -0
  17. package/.compiiile/src/layouts/WorkspaceLayout.astro +58 -0
  18. package/.compiiile/src/pages/404.astro +17 -0
  19. package/.compiiile/src/pages/[...path].astro +61 -0
  20. package/.compiiile/src/style/code-theme.scss +30 -0
  21. package/.compiiile/src/style/index.scss +36 -0
  22. package/.compiiile/src/style/layouts.scss +43 -0
  23. package/.compiiile/src/style/print.scss +80 -0
  24. package/.compiiile/src/style/slides.scss +79 -0
  25. package/.compiiile/src/style/texts.scss +92 -0
  26. package/.compiiile/src/style/variables.scss +47 -0
  27. package/.compiiile/src/utils/searchIndex.js +28 -0
  28. package/.compiiile/src/utils/styles.js +9 -0
  29. package/.eslintrc.cjs +15 -0
  30. package/.github/FUNDING.yml +2 -0
  31. package/.prettierignore +1 -0
  32. package/.prettierrc.json +9 -0
  33. package/CHANGELOG.md +25 -0
  34. package/CONTRIBUTING.md +31 -0
  35. package/LICENCE.md +674 -0
  36. package/README.md +273 -0
  37. package/bin/cli.js +5 -0
  38. package/bin/config.js +137 -0
  39. package/bin/vitePluginCompiiile/index.js +32 -0
  40. package/bin/vitePluginCompiiile/markdownConfig.js +30 -0
  41. package/bin/vitePluginCompiiile/models/Context.js +138 -0
  42. package/bin/vitePluginCompiiile/models/FileListItem.js +10 -0
  43. package/bin/vitePluginCompiiile/models/FilesTreeItem.js +8 -0
  44. package/bin/vitePluginCompiiile/models/RouteListItem.js +9 -0
  45. package/bin/vitePluginCompiiile/rehypeHandleYamlMatterPlugin.js +8 -0
  46. package/bin/vitePluginCompiiile/rehypeImagePlugin.js +51 -0
  47. package/bin/vitePluginCompiiile/rehypeLinkPlugin.js +20 -0
  48. package/build.js +16 -0
  49. package/compiiile.config.js +6 -0
  50. package/dist/style.css +1 -0
  51. package/markdown-preview.md +242 -0
  52. package/package.json +81 -0
  53. package/slides-preview.mdx +39 -0
  54. package/src/env.d.ts +1 -0
  55. package/tsconfig.json +6 -0
package/README.md ADDED
@@ -0,0 +1,273 @@
1
+ # Compiiile
2
+
3
+ > Compiiile is the most convenient way to render a folder containing markdown files. Previewing and searching markdown files has never been that easy (it's really just a command away !) :sparkles:
4
+
5
+ ## Preview
6
+
7
+ ![Demo](https://i.imgur.com/nCZlWDE.gif)
8
+
9
+ > Check the live demo here: https://compiiile.me/
10
+
11
+ ## Purpose
12
+
13
+ I document everything in markdown and have always been frustrated not having a simple tool to just **preview** a whole
14
+ folder, being able to **search** through it, make **slides** out of it, and get a **production-ready** build of all the files as a knowledge base. On
15
+ top of that, finding a tool with a sweet and simple UI is not that easy.
16
+
17
+ That's what Compiiile does. And it does it hassle-free !
18
+
19
+ ## Features
20
+
21
+ - [x] 📦 **No config required, everything just works out of the box, without changing your files** (resolves images and relative links (cross-references), print-ready rendering)
22
+ - [x] 🌱 Available everywhere with static files deployment: just host it somewhere and access it in any browser on your computer, phone or whatever you are using
23
+ - [x] :link: Quick access to your files via the navbar and links to the previous and next file (with table of content generation)
24
+ - [x] :tv: Display some files as slides
25
+ - [x] :mag: **Full-text quick search with content preview**
26
+ - [x] :zap: Hot-reload content preview as you edit it
27
+ - [x] :tada: Supports MDX files
28
+ - [x] :bulb: Can serve as knowledge base
29
+ - [x] :wrench: Customizable by env variables or config file, it's up to you
30
+ - [x] :star2: You get it, it simply does the job, period.
31
+
32
+ ### What Compiiile isn't
33
+
34
+ - It's not a markdown editor, there are already plenty available, just choose the one that works best for you, even the simplest text editor will do.
35
+ - It's not like VuePress, VitePress, Docusaurus or Notion. Compiiile's goal is to stay simple and stupidly easy without any configuration.
36
+
37
+ > The goal is to help people rely purely on a **language** (_markdown_), not on _any_ platform.
38
+
39
+ ## Installation
40
+
41
+ You can install Compiiile either globally or per-project:
42
+
43
+ ### Globally
44
+
45
+ Open a terminal and type one of these commands, whether using [npm](https://www.npmjs.com/) or [yarn](https://yarnpkg.com/) depending on which package manager you are using:
46
+
47
+ ```bash
48
+ yarn global add @compiiile/compiiile # install globally with yarn
49
+ # or
50
+ npm install -g @compiiile/compiiile # install globally with npm
51
+ ```
52
+
53
+ ### Per-project
54
+
55
+ Open a terminal inside the folder containing your markdown files. Then, add Compiiile as a local command using yarn or npm:
56
+
57
+ ```bash
58
+ yarn add @compiiile/compiiile # install as a project dependency with yarn
59
+ # or
60
+ npm install @compiiile/compiiile # install as a project dependency with npm
61
+ ```
62
+
63
+ ## Quick start
64
+
65
+ To make yourself an idea and quickly get started using Compiiile, here are some commands that you can run in your terminal to get Compiiile running with a couple of markdown files as tests:
66
+
67
+ ```bash
68
+ mkdir test-compiiile && cd test-compiiile # creating a new folder and go into this folder
69
+ yarn global add @compiiile/compiiile # installing compiiile as global dependency using yarn
70
+ echo '# Test Compiiile\n\n> Here is a blockquote for you\n\n## Your markdown awaits below' > README.md # a first test file
71
+ echo '---\nasSlides: true\n---\n\n# Slide 1\n\n---\n\n# And this is slide 2' > slides.md # a second test file as slides
72
+ compiiile --title="📚 Compiiile" # running Compiiile for these 2 files
73
+ ```
74
+
75
+ Et voilà, you should be able to preview your files in your browser :tada:.
76
+
77
+ ## Usage
78
+
79
+ Once installed, 3 commands are available to see your beautiful markdown files :eyes::
80
+
81
+ - `compiiile dev` : creates a web server to check your markdown files (alias to only `compiiile`)
82
+ - `compiiile build` : builds all the files for you to serve them production-ready
83
+ - `compiiile preview` : preview your production-ready build
84
+
85
+ You can run the command you want in your terminal while being in the desired folder.
86
+
87
+ To use these commands inside a javascript project, you just have to add these commands to the `scripts` section of your
88
+ `package.json` file like so:
89
+
90
+ ```json
91
+ {
92
+ "scripts": {
93
+ "dev": "compiiile dev",
94
+ "build": "compiiile build",
95
+ "preview": "compiiile preview"
96
+ }
97
+ }
98
+ ```
99
+
100
+ You can run these scripts by running `yarn <script>` or `npm run <script>` in your terminal (replacing `<script>`
101
+ with your script name).
102
+
103
+ The build command builds your files in a `.compiiile/dist` folder at the root of your current directory by default.
104
+ You can override this parameter (see below on how to use a custom configuration).
105
+
106
+ ## Write some markdown (Compiiile-specific parameters)
107
+
108
+ The goal of this project is to get it running **without changing any markdown files already written**.
109
+ Yet, there are some things to consider to configure some files:
110
+
111
+ ### Slides
112
+
113
+ To make a file usable as slides, you only have to add this parameter to the `frontmatter` of your markdown
114
+ file:
115
+
116
+ ```md
117
+ ---
118
+ asSlides: true
119
+ ---
120
+ ```
121
+
122
+ If you are not acquainted with frontmatter, it's just some file-specific parameters that you can put at the very
123
+ beginning of your file to be processed (make sure to separate frontmatter values from your content with an empty line after the last `---`).
124
+
125
+ By adding the frontmatter parameter, the page will directly open up as slides.
126
+
127
+ To separate your slides, just separate the content of your markdown with:
128
+
129
+ ```md
130
+ ---
131
+ ```
132
+
133
+ > There must be an empty line before and after the `---`
134
+
135
+ :star2: You can make your slides print-ready by adding the `print-pdf` query parameter to your page, like: `https://compiiile.me/s/slides-preview?print-pdf`.
136
+
137
+ Other frontmatter keys will be handled:
138
+
139
+ - `title`: set the title to be displayed in the navbar and for SEO
140
+ - `description`: set the description for SEO
141
+
142
+ ### Routing
143
+
144
+ The home page of Compiiile (`/`) points to a `README.md` file located at the root of your folder.
145
+
146
+ ## Custom configuration
147
+
148
+ Here is the list of parameters that you can set to customize Compiiile (none are required):
149
+
150
+ | Parameter | Type | Description |
151
+ | ---------------------- | ---------- | ----------------------------------------------------------------------------------------------- |
152
+ | `title` | `string` | The title to display on the top-left of the User Interface |
153
+ | `description` | `string` | The description that is rendered by default for the SEO |
154
+ | `logo` | `string` | The relative path of the logo to display in the TopBar and as favicon |
155
+ | `logoUrl` | `string` | The url to go to when clicking on the logo, defaults to the home page if not set |
156
+ | `dest` | `string` | The folder in which to build files, defaults to `./.compiiile/dist` |
157
+ | `siteUrl` | `string` | The url of the website in production (without trailing slash), used for the SEO tag `og:image` |
158
+ | `astroConfig` | `Object` | Override [default Astro config](https://docs.astro.build/en/reference/configuration-reference/) |
159
+ | `vite.server.fs.allow` | `string[]` | Add local paths to vite's server fs allow list |
160
+
161
+ You can use these parameters in 2 ways:
162
+
163
+ ### Script arguments
164
+
165
+ Config parameters can be passed by script arguments.
166
+
167
+ For example, if you want to change the title, just run Compiiile like so:
168
+
169
+ ```bash
170
+ compiiile dev --title="My knowledge base 📚"
171
+ ```
172
+
173
+ ### Config file
174
+
175
+ Another way to set default config parameters is to set them in a dedicated file named `compiiile.config.js` in the
176
+ root of your folder.
177
+
178
+ This should export an object, like in this example that shows common use cases :
179
+
180
+ ```js
181
+ export default {
182
+ title: "Compiiile",
183
+ logo: "./my-logo.png",
184
+ dest: "my-custom-build-folder"
185
+ }
186
+ ```
187
+
188
+ > ⚠️ You should bear in mind that script arguments have priority over config file parameters.
189
+
190
+ ## Use MDX
191
+
192
+ v2 of Compiiile allows you to use MDX files with Vue components.
193
+
194
+ For it to work, you should install some dependencies in your project folder: `yarn add vue astro fzf` (or `npm install vue astro fzf`).
195
+
196
+ Let's say we have Vue a component `Test.vue` making an API request and listing results:
197
+
198
+ ```vue
199
+ <template>
200
+ <div>
201
+ <h2>Random users fetched from an API:</h2>
202
+ <ul>
203
+ <li v-for="user in users">
204
+ {{ user.name.first }} <span class="uppercase">{{ user.name.last }}</span>
205
+ </li>
206
+ </ul>
207
+ </div>
208
+ </template>
209
+
210
+ <script>
211
+ export default {
212
+ name: "Test",
213
+ data() {
214
+ return {
215
+ users: []
216
+ }
217
+ },
218
+ methods: {
219
+ async loadUsers() {
220
+ const res = await fetch("https://randomuser.me/api/?results=10")
221
+ this.users = (await res.json()).results
222
+ }
223
+ },
224
+ async mounted() {
225
+ await this.loadUsers()
226
+ }
227
+ }
228
+ </script>
229
+
230
+ <style scoped>
231
+ .uppercase {
232
+ text-transform: uppercase;
233
+ }
234
+ </style>
235
+ ```
236
+
237
+ You can use it your MDX file like so:
238
+
239
+ ```
240
+ import Test from "./Test.vue"
241
+
242
+ <Test client:load />
243
+ ```
244
+
245
+ You should use [Astro's client directives](https://docs.astro.build/en/reference/directives-reference/#client-directives) to load your component's script.
246
+
247
+ ## Special thanks
248
+
249
+ - [Astro](https://github.com/withastro/astro) for enabling us developers to make lightweight websites
250
+ - [fzf-for-js](https://github.com/ajitid/fzf-for-js) for the search feature
251
+ - [reveal.js](https://revealjs.com/) for displaying markdown files as slides
252
+ - [Vite](https://vitejs.dev/) for helping modern frontend developers keep their mental health sane :heart:
253
+
254
+ ## Contributing
255
+
256
+ Contributions are welcome after discussing the object of your contribution in the `Issues` pages (because the goal is to keep this project really simple and straightforward).
257
+
258
+ You can read more about it and the roadmap in the [dedicated contributing guide](./CONTRIBUTING.md).
259
+
260
+ ## Support
261
+
262
+ Open-source is a wonderful thing, so please if you found this project useful or use it as a part of a commercial project, **consider making a donation**.
263
+ You can do it either via [GitHub donations](https://github.com/sponsors/AlbanCrepel) or via [my ko-fi page](https://ko-fi.com/alban_crepel) where you can make a one-time or monthly donation by PayPal or card.
264
+ This allows you to use Compiiile as a **pay-what-you-want** service if you are not part of a non-profit project. But if you are **making any revenue** using this project or even use it as a trainer, **making a donation would be expected**.
265
+ You can always contact me for a custom use of this project and any licence issue.
266
+
267
+ Thank you :heart:
268
+
269
+ ## Licence
270
+
271
+ This project is licensed under the terms of the GNU General Public License v3.0.
272
+
273
+ See [LICENCE.md](./LICENCE.md).
package/bin/cli.js ADDED
@@ -0,0 +1,5 @@
1
+ #! /usr/bin/env node
2
+
3
+ import { astroConfig, run } from "./config.js"
4
+
5
+ await run(astroConfig)
package/bin/config.js ADDED
@@ -0,0 +1,137 @@
1
+ import { build, dev, preview } from "astro"
2
+ import vue from "@astrojs/vue"
3
+ import compiiile from "./vitePluginCompiiile/index.js"
4
+ import mdx from "@astrojs/mdx"
5
+ import path from "node:path"
6
+ import { copyFileSync, cpSync } from "node:fs"
7
+ import markdownConfig from "./vitePluginCompiiile/markdownConfig.js"
8
+
9
+ const source = process.cwd()
10
+ process.env.COMPIIILE_SOURCE = source
11
+
12
+ const CONFIG_FILE = "compiiile.config.js"
13
+
14
+ import yargs from "yargs/yargs"
15
+ import { hideBin } from "yargs/helpers"
16
+
17
+ import { readFile } from "fs/promises"
18
+ const packageJSON = JSON.parse(await readFile(new URL("../package.json", import.meta.url)))
19
+
20
+ /*
21
+ Order of options by priority:
22
+ 1. command arguments
23
+ 2. user-defined config in dedicated file
24
+ 3. default config as fallback
25
+ */
26
+ let configFromFile = {}
27
+ try {
28
+ configFromFile = (await import(path.join(source, CONFIG_FILE))).default
29
+ } catch {
30
+ // This means that no config file was provided: getting parameters from script parameters instead
31
+ }
32
+
33
+ const argv = yargs(hideBin(process.argv))
34
+ .parserConfiguration({
35
+ "deep-merge-config": true
36
+ })
37
+ .alias("v", "version")
38
+ .config(configFromFile)
39
+ .command("dev", "launch development server")
40
+ .command("build", "build")
41
+ .command("preview", "preview")
42
+ .help()
43
+ .version(packageJSON.version).argv
44
+
45
+ process.env.VITE_COMPIIILE_SITE_URL = argv.siteUrl ?? ""
46
+
47
+ process.env.VITE_COMPIIILE_TITLE = argv.title ?? ""
48
+ process.env.VITE_COMPIIILE_DESCRIPTION = argv.description ?? ""
49
+
50
+ process.env.VITE_COMPIIILE_LOGO_URL = argv.logoUrl ?? ""
51
+
52
+ // Handling logo and favicon
53
+ process.env.VITE_COMPIIILE_LOGO = null
54
+
55
+ const publicDir = path.resolve(source, "./.compiiile/public")
56
+
57
+ if (argv.logo) {
58
+ try {
59
+ cpSync(new URL("../.compiiile/public", import.meta.url).pathname, publicDir, { recursive: true })
60
+ copyFileSync(path.resolve(source, argv.logo), path.resolve(publicDir, "favicon.png"))
61
+ // Set the logo to be displayed on the top bar if we were able to copy
62
+ process.env.VITE_COMPIIILE_LOGO = argv.logo
63
+ } catch (e) {
64
+ console.log(e)
65
+ console.error("Could not load provided logo: set a relative url from the current folder")
66
+ }
67
+ }
68
+
69
+ // Making sure fonts are accessible by vite's server
70
+ import { createRequire } from "node:module"
71
+ const require = createRequire(import.meta.url)
72
+ const pathName = require.resolve("@fontsource-variable/archivo")
73
+ import { packageDirectory } from "pkg-dir"
74
+ const viteServerFsAllowList = [source, new URL("../", import.meta.url).pathname, path.resolve(pathName, "../../")]
75
+ const packageDir = await packageDirectory()
76
+ if (packageDir) {
77
+ viteServerFsAllowList.push(packageDir)
78
+ }
79
+
80
+ const astroConfig = {
81
+ root: new URL("../.compiiile", import.meta.url).pathname,
82
+ srcDir: new URL("../.compiiile/src", import.meta.url).pathname,
83
+ outDir: path.join(source, argv.dest || ".compiiile/dist"),
84
+ ...(argv.logo ? { publicDir } : {}),
85
+ integrations: [vue({ appEntrypoint: "/src/app.js" }), mdx(), ...(configFromFile.integrations ?? [])],
86
+ vite: {
87
+ plugins: [compiiile()],
88
+ resolve: {
89
+ alias: {
90
+ "@source": source
91
+ }
92
+ },
93
+ server: {
94
+ fs: {
95
+ allow: [...viteServerFsAllowList, ...(configFromFile["vite.server.fs.allow"] ?? [])]
96
+ }
97
+ }
98
+ },
99
+ markdown: markdownConfig,
100
+ output: "static",
101
+ base: "/",
102
+ trailingSlash: "never",
103
+ devToolbar: {
104
+ enabled: false
105
+ },
106
+ ...(configFromFile.astroConfig ?? {})
107
+ }
108
+
109
+ process.env.VITE_COMPIIILE_BASE = astroConfig.base
110
+ if (process.env.VITE_COMPIIILE_BASE !== "/" && process.env.VITE_COMPIIILE_BASE.endsWith("/")) {
111
+ process.env.VITE_COMPIIILE_BASE = process.env.VITE_COMPIIILE_BASE.slice(0, -1)
112
+ }
113
+
114
+ const run = async (astroConfig) => {
115
+ const IS_DEV = argv._.length === 0 || argv._.includes("dev")
116
+ const IS_BUILD = argv._.includes("build")
117
+ const IS_PREVIEW = argv._.includes("preview")
118
+
119
+ const NODE_ENV_DEVELOPMENT = "development"
120
+ const NODE_ENV_PRODUCTION = "production"
121
+ if (IS_DEV) {
122
+ process.env.NODE_ENV = NODE_ENV_DEVELOPMENT
123
+
124
+ const devServer = await dev(astroConfig)
125
+ devServer.watcher.add([source])
126
+ } else if (IS_BUILD) {
127
+ process.env.NODE_ENV = NODE_ENV_PRODUCTION
128
+
129
+ await build(astroConfig)
130
+ } else if (IS_PREVIEW) {
131
+ process.env.NODE_ENV = NODE_ENV_PRODUCTION
132
+
133
+ await preview(astroConfig)
134
+ }
135
+ }
136
+
137
+ export { astroConfig, run }
@@ -0,0 +1,32 @@
1
+ import Context from "./models/Context.js"
2
+
3
+ const source = "."
4
+
5
+ export default function compiiile() {
6
+ const virtualModuleId = "virtual:compiiile"
7
+ const resolvedVirtualModuleId = "\0" + virtualModuleId
8
+
9
+ return {
10
+ name: "compiiile",
11
+ resolveId(id) {
12
+ if (id === virtualModuleId) {
13
+ return resolvedVirtualModuleId
14
+ }
15
+ },
16
+ async load(id) {
17
+ if (id !== resolvedVirtualModuleId) {
18
+ return
19
+ }
20
+
21
+ const context = new Context()
22
+ context.filesTree = await context.scanDirectoryRecursively(source)
23
+ process.env.context = JSON.stringify(context)
24
+
25
+ return `const fileList = ${JSON.stringify(context.fileList)};\n\n
26
+ const filesTree = ${JSON.stringify(context.filesTree)};\n\n
27
+ const routeList = ${JSON.stringify(context.routeList)};\n\n
28
+ const site = ${JSON.stringify(context.site)};\n\n
29
+ export { fileList, filesTree, routeList, site };`
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,30 @@
1
+ import emoji from "remark-emoji"
2
+ import rehypeImagePlugin from "./rehypeImagePlugin.js"
3
+ import rehypeLinkPlugin from "./rehypeLinkPlugin.js"
4
+ import rehypeSlug from "rehype-slug"
5
+ import rehypeAutolinkHeadings from "rehype-autolink-headings"
6
+ import { h } from "hastscript"
7
+ import rehypeHandleYamlMatterPlugin from "./rehypeHandleYamlMatterPlugin.js"
8
+
9
+ export default {
10
+ remarkPlugins: [emoji],
11
+ rehypePlugins: [
12
+ rehypeImagePlugin,
13
+ rehypeLinkPlugin,
14
+ rehypeSlug,
15
+ [
16
+ rehypeAutolinkHeadings,
17
+ {
18
+ behavior: "prepend",
19
+ content: () => [h("span", "#")],
20
+ properties: {
21
+ ariaHidden: true,
22
+ tabIndex: -1,
23
+ class: "header-anchor"
24
+ }
25
+ }
26
+ ],
27
+ rehypeHandleYamlMatterPlugin
28
+ ],
29
+ shikiConfig: { theme: "css-variables" }
30
+ }
@@ -0,0 +1,138 @@
1
+ import path from "node:path"
2
+ import fs from "node:fs"
3
+ import { v4 as uuidv4 } from "uuid"
4
+ import FileListItem from "./FileListItem.js"
5
+ import FilesTreeItem from "./FilesTreeItem.js"
6
+ import RouteListItem from "./RouteListItem.js"
7
+ import { createMarkdownProcessor } from "@astrojs/markdown-remark"
8
+ import markdownConfig from "../markdownConfig.js"
9
+ import { unemojify } from "node-emoji"
10
+ import slugify from "slugify"
11
+
12
+ export default class {
13
+ WORKSPACE_BASE_PATH = "c"
14
+ SLIDES_BASE_PATH = "s"
15
+
16
+ constructor() {
17
+ this.fileList = []
18
+ this.filesTree = []
19
+ this.routeList = []
20
+ this.fileRouteMap = {}
21
+
22
+ this.site = {
23
+ title: process.env.VITE_COMPIIILE_TITLE !== "" ? process.env.VITE_COMPIIILE_TITLE : undefined,
24
+ description:
25
+ process.env.VITE_COMPIIILE_DESCRIPTION !== "" ? process.env.VITE_COMPIIILE_DESCRIPTION : undefined,
26
+ logo: process.env.VITE_COMPIIILE_LOGO !== "null" ? process.env.VITE_COMPIIILE_LOGO : undefined,
27
+ logoUrl: process.env.VITE_COMPIIILE_LOGO_URL !== "" ? process.env.VITE_COMPIIILE_LOGO_URL : undefined,
28
+ siteUrl: process.env.VITE_COMPIIILE_SITE_URL !== "" ? process.env.VITE_COMPIIILE_SITE_URL : undefined,
29
+ base: process.env.VITE_COMPIIILE_BASE
30
+ }
31
+ }
32
+
33
+ generateRoutePathFromFilePath(filePath, hash = "", asSlides = false) {
34
+ const filePathWithoutExtension = filePath.substring(0, filePath.lastIndexOf("."))
35
+ const sluggifiedPath = filePathWithoutExtension
36
+ .split("/")
37
+ .map((val) => slugify(val, { lower: true }))
38
+ .join("/")
39
+
40
+ if (sluggifiedPath === "readme") {
41
+ if (process.env.VITE_COMPIIILE_BASE !== "/") {
42
+ return process.env.VITE_COMPIIILE_BASE
43
+ }
44
+
45
+ return "/"
46
+ }
47
+ return `${
48
+ process.env.VITE_COMPIIILE_BASE.endsWith("/")
49
+ ? process.env.VITE_COMPIIILE_BASE.slice(0, -1)
50
+ : process.env.VITE_COMPIIILE_BASE
51
+ }/${asSlides ? this.SLIDES_BASE_PATH : this.WORKSPACE_BASE_PATH}/${sluggifiedPath}${hash}`
52
+ }
53
+
54
+ async scanDirectoryRecursively(directoryPath) {
55
+ const fileArray = []
56
+
57
+ const collator = new Intl.Collator(undefined, {
58
+ numeric: true,
59
+ sensitivity: "base"
60
+ })
61
+
62
+ const files = fs.readdirSync(directoryPath).sort(collator.compare)
63
+
64
+ for (let file of files) {
65
+ if (
66
+ ![
67
+ ".vuepress",
68
+ ".git",
69
+ "node_modules",
70
+ "compiiile",
71
+ "bin",
72
+ ".idea",
73
+ ".DS_Store",
74
+ ".gitignore",
75
+ "vendor"
76
+ ].includes(file)
77
+ ) {
78
+ const filePath = path.join(directoryPath, file)
79
+ const isDirectory = fs.statSync(filePath).isDirectory()
80
+ const uuid = uuidv4()
81
+ const fileName = path.parse(filePath).name
82
+ const isReadmeFile = !isDirectory && filePath.toLowerCase().match(/^readme\.mdx?$/)
83
+
84
+ let filesTreeItem = new FilesTreeItem(uuid, fileName)
85
+
86
+ if (isDirectory) {
87
+ filesTreeItem.isDirectory = true
88
+ filesTreeItem.children = await this.scanDirectoryRecursively(filePath)
89
+ }
90
+
91
+ if (path.extname(file).match(/^\.mdx?$/) || filesTreeItem?.children.length > 0) {
92
+ if (isReadmeFile) {
93
+ fileArray.unshift(filesTreeItem)
94
+ } else {
95
+ fileArray.push(filesTreeItem)
96
+ }
97
+
98
+ if (!isDirectory) {
99
+ const fileListItem = new FileListItem(uuid)
100
+ const markdownContent = fs.readFileSync(filePath, {
101
+ encoding: "utf8"
102
+ })
103
+
104
+ const markdownProcessor = await createMarkdownProcessor(markdownConfig)
105
+ const renderedMarkdown = await markdownProcessor.render(markdownContent)
106
+
107
+ fileListItem.textContent = unemojify(
108
+ renderedMarkdown.code
109
+ .replace(/<a.*aria-hidden.*>.*?<\/a>|<[^>]*>?/gi, "")
110
+ .replace(/[\r\n]{2,}/g, "\n")
111
+ )
112
+ const meta = renderedMarkdown.metadata.frontmatter
113
+ fileListItem.title = meta.title || fileName
114
+ fileListItem.meta = meta
115
+ fileListItem.meta.title = fileListItem.meta.title || fileListItem.title
116
+ fileListItem.fullPath = filePath
117
+
118
+ const routePath = this.generateRoutePathFromFilePath(filePath, "", fileListItem.meta.asSlides)
119
+
120
+ if (isReadmeFile) {
121
+ this.fileList.unshift(fileListItem)
122
+ } else {
123
+ this.fileList.push(fileListItem)
124
+ }
125
+
126
+ // `asSlides` frontmatter param is passed via the meta
127
+ const routeListItem = new RouteListItem(routePath, uuid, fileName, filePath, fileListItem.meta)
128
+ fileListItem.routePath = routeListItem.path
129
+ this.fileRouteMap[filePath] = routeListItem.path
130
+ this.routeList.push(routeListItem)
131
+ }
132
+ }
133
+ }
134
+ }
135
+
136
+ return fileArray
137
+ }
138
+ }
@@ -0,0 +1,10 @@
1
+ export default class {
2
+ constructor(uuid, textContent = null, title, fullPath, meta = {}, routePath = null) {
3
+ this.uuid = uuid
4
+ this.textContent = textContent
5
+ this.title = title
6
+ this.fullPath = fullPath
7
+ this.meta = meta
8
+ this.routePath = routePath
9
+ }
10
+ }
@@ -0,0 +1,8 @@
1
+ export default class {
2
+ constructor(uuid, name, isDirectory = false, children = []) {
3
+ this.uuid = uuid
4
+ this.name = name
5
+ this.isDirectory = isDirectory
6
+ this.children = children
7
+ }
8
+ }
@@ -0,0 +1,9 @@
1
+ export default class {
2
+ constructor(path, name, title, fullPath, meta) {
3
+ this.path = path
4
+ this.name = name
5
+ this.title = title
6
+ this.fullPath = fullPath
7
+ this.meta = meta
8
+ }
9
+ }
@@ -0,0 +1,8 @@
1
+ import { matter } from "vfile-matter"
2
+
3
+ export default function rehypeHandleYamlMatterPlugin() {
4
+ return function (_, file) {
5
+ matter(file)
6
+ file.data.astro.frontmatter = file.data.matter
7
+ }
8
+ }