-
Notifications
You must be signed in to change notification settings - Fork 54
/
Copy pathindex.js
103 lines (85 loc) · 3.2 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
const path = require("path")
const { default: twoslash } = require("remark-shiki-twoslash")
/**
* @param {import("@docusaurus/types").DocusaurusContext} context
* @param {import("remark-shiki-twoslash").Settings} pluginOptions
* @returns {import("@docusaurus/types").Preset}
*/
function preset(context, pluginOptions) {
const options = { ...pluginOptions, wrapFragments: true }
// So, how do we hijack the code renderer? We mostly override the user's configuration for
// the presets.
if (!context.siteConfig.presets || !context.siteConfig.plugins) {
throw Error("Couldn't find either a preset or a plugin")
}
// Available presets & plugins
// We could parse out the repeated parts from the strings but
// I think it's better this way as a way of showing that twoslash could
// technically support all kinds of presets, not just official ones
const presets = [["@docusaurus/preset-classic", "classic"]]
const plugins = [
["@docusaurus/plugin-content-docs", "content-docs"],
["@docusaurus/plugin-content-blog", "content-blog"],
["@docusaurus/plugin-content-pages", "content-pages"],
]
// Flag to keep track if at least one of the presets or the plugins are installed
let flag = false
/**
* Checks if b is in a
* @param {string[][]} a
* @param {string | [string] | [string, any]} b
*/
const contains = (a, b) => a.flat().includes(typeof b === "string" ? b : b[0])
/**
* Structure `a` into proper `[a, {}]`
* @param {string | [string] | [string, any]} a
* @returns {[string, any]}
* - `[a, {}]` if `a` is `string`
* - `[a[0], {}]` if `a` is `[string]`
* - `a` if `a` is already `[string, {}]`
*/
const structure = a => (typeof a === "string" ? [a, {}] : a.length === 1 ? [a[0], {}] : a)
// Adds remark-shiki-twoslash into beforeDefaultRemarkPlugins
const addTwoslash = a => {
flag = true
if (!a.beforeDefaultRemarkPlugins) {
a.beforeDefaultRemarkPlugins = []
}
a.beforeDefaultRemarkPlugins.push([twoslash, options])
return a
}
context.siteConfig.presets = context.siteConfig.presets.map(preset => {
if (!contains(presets, preset)) {
return preset
}
const output = structure(preset)
const sections = ["docs", "blog", "pages"]
for (const section of sections) {
// If the plugin is disabled, keep it disabled
if (output[1][section] === false) continue
if (!output[1][section]) output[1][section] = {}
addTwoslash(output[1][section])
}
return output
})
context.siteConfig.plugins = context.siteConfig.plugins.map(plugin => {
if (typeof plugin === "function" || (Array.isArray(plugin) && typeof plugin[0] === "function")) {
return plugin
}
// if the plugin is not supported
if (!contains(plugins, plugin)) {
return plugin
}
return addTwoslash(structure(plugin))
})
if (!flag) {
throw Error(`
Couldn't find a preset or a plugin supported by twoslash
Make sure you installed one of these presets [ ${presets.map(p => p[0]).join(", ")} ],
or one of these plugins [ ${plugins.map(p => p[0]).join(", ")} ].\n`)
}
return {
themes: [path.resolve(__dirname, "./docusaurus-theme-shiki-twoslash")],
}
}
module.exports = preset