do11y 0.2.10 → 0.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -84,16 +84,49 @@ interface Options {
84
84
  /**
85
85
  * The code highlighter.
86
86
  * - Markdown code blocks
87
- * - `.vue?highlight` & `.vue?highlight&lang=css` imports
87
+ * - `.vue?highlight`, `.vue?highlight&lang=css` & `.vue?highlight&styleless` imports
88
88
  * - `highlightedSource` and `highlightedCssSource` props in SandboxIframe
89
89
  *
90
90
  * If using multiple themes - you can set the `data-theme` attribute
91
91
  * to switch between them, e.g. `data-theme="vitesse-light"`.
92
92
  */
93
93
  highlighter?: {
94
+ /**
95
+ * The available themes.
96
+ * The default shiki themes are always included.
97
+ */
94
98
  themes: (ThemeInput | StringLiteralUnion<BundledTheme, string>)[];
99
+
100
+ /**
101
+ * What the default theme should be.
102
+ * @default "The first theme in the array"
103
+ */
95
104
  defaultTheme?: string | StringLiteralUnion<BundledTheme, string>;
105
+
106
+ /**
107
+ * Custom transformers.
108
+ *
109
+ * These Shiki's default transformers are always included:
110
+ * - transformerNotationHighlight
111
+ * - transformerNotationDiff
112
+ * - transformerNotationErrorLevel
113
+ */
96
114
  transformers?: ShikiTransformer[];
115
+
116
+ /**
117
+ * If comments should be filtered.
118
+ * - Passing `true` removes all comments
119
+ * - While `string[]` acts as a filter - removing comments that `include` any of these strings in them
120
+ * - `false` keeps all comments
121
+ *
122
+ * @default ["prettier-ignore"]
123
+ */
124
+ removeComments?: boolean | string[];
125
+
126
+ /**
127
+ * If any postprocessing should be done.
128
+ * The element is a JSDOM HTMLPreElement.
129
+ */
97
130
  postprocess?: (pre: HTMLPreElement) => void;
98
131
  };
99
132
 
@@ -21,6 +21,13 @@ export interface SandboxIframeProps {
21
21
  * @do11y Automatically passed.
22
22
  */
23
23
  highlightedSource: string;
24
+ /**
25
+ * HTML string containing the highlighted source code,
26
+ * without any of the style tags.
27
+ *
28
+ * @do11y Automatically passed.
29
+ */
30
+ highlightedStylelessSource: string;
24
31
  /**
25
32
  * HTML string containing the highlighted source code,
26
33
  * with all the style tags compiled to CSS.
@@ -24,6 +24,8 @@ const resolveOptions = async () => {
24
24
  themes: options.highlighter?.themes ?? [],
25
25
  themesInput,
26
26
  transformers: options.highlighter?.transformers || [],
27
+ postprocess: options.highlighter?.postprocess,
28
+ removeComments: options.highlighter?.removeComments ?? ["prettier-ignore"],
27
29
  },
28
30
  };
29
31
  };
@@ -30,6 +30,52 @@ export const highlightCode = (code, lang) => {
30
30
  }
31
31
  },
32
32
  },
33
+ {
34
+ name: "remove-unwanted-comments",
35
+ tokens(tokens) {
36
+ const filter = do11yOptions.highlighter.removeComments;
37
+ if (filter === false) {
38
+ return tokens;
39
+ }
40
+ const result = [];
41
+ let previousLineWasRemoved = false;
42
+ for (const line of tokens) {
43
+ previousLineWasRemoved = false;
44
+ const filteredLine = [];
45
+ let hasComment = false;
46
+ for (const token of line) {
47
+ const isUnwantedComment = token.explanation?.some((exp) => {
48
+ const isComment = exp.scopes.some((s) => s.scopeName.startsWith("comment"));
49
+ if (!isComment) {
50
+ return false;
51
+ }
52
+ return typeof filter === "boolean"
53
+ ? true
54
+ : filter.some((query) => exp.content.includes(query));
55
+ });
56
+ if (isUnwantedComment) {
57
+ hasComment = true;
58
+ }
59
+ else {
60
+ filteredLine.push(token);
61
+ }
62
+ }
63
+ /**
64
+ * Remove lines that become empty after removing comments.
65
+ * Additionally, if the next line after a removed comment line is empty too - remove it.
66
+ */
67
+ if (hasComment || previousLineWasRemoved) {
68
+ const isAllWhitespace = filteredLine.every((token) => !token.content.trim());
69
+ previousLineWasRemoved = isAllWhitespace;
70
+ if (isAllWhitespace) {
71
+ continue;
72
+ }
73
+ }
74
+ result.push(filteredLine);
75
+ }
76
+ return result;
77
+ },
78
+ },
33
79
  ],
34
80
  });
35
81
  };
@@ -48,9 +94,21 @@ export default () => {
48
94
  viteDevServer = server;
49
95
  },
50
96
  async transform(_, id) {
51
- if (id.endsWith(".vue?highlight") || id.endsWith(".vue?highlight&lang=css")) {
52
- const path = id.replace("?highlight", "").replace("&lang=css", "");
97
+ if (id.endsWith(".vue?highlight") ||
98
+ id.endsWith(".vue?highlight&lang=css") ||
99
+ id.endsWith(".vue?highlight&styleless")) {
100
+ const path = id
101
+ .replace("?highlight", "")
102
+ .replace("&lang=css", "")
103
+ .replace("&styleless", "");
53
104
  const source = readFileSync(path, "utf-8");
105
+ const sourceWithoutStyles = source.replace(/\n<style\b[^>]*>[\s\S]*?<\/style>/gi, "");
106
+ if (id.endsWith("styleless")) {
107
+ return {
108
+ code: `export default ${JSON.stringify(await highlightAndFormatCode(path, sourceWithoutStyles))};`,
109
+ moduleType: "js",
110
+ };
111
+ }
54
112
  /**
55
113
  * Getting the code from `load` does not work during development,
56
114
  * so we return the original code during development.
@@ -70,7 +128,6 @@ export default () => {
70
128
  });
71
129
  return code?.replace(/^(export default ")/, "").replace(/"$/, "");
72
130
  };
73
- const sourceWithoutStyles = source.replace(/\n<style\b[^>]*>[\s\S]*?<\/style>/gi, "");
74
131
  const stylesheets = parseVue(source).descriptor.styles.map((style, i) => {
75
132
  /* prettier-ignore */
76
133
  return !style.lang || style.lang === "css"
@@ -31,16 +31,45 @@ export interface Options extends MarkdownPluginOptions {
31
31
  /**
32
32
  * The code highlighter.
33
33
  * - Markdown code blocks
34
- * - `.vue?highlight` & `.vue?highlight&lang=css` imports
34
+ * - `.vue?highlight`, `.vue?highlight&lang=css` & `.vue?highlight&styleless` imports
35
35
  * - `highlightedSource` and `highlightedCssSource` props in SandboxIframe
36
36
  *
37
37
  * If using multiple themes - you can set the `data-theme` attribute
38
38
  * to switch between them, e.g. `data-theme="vitesse-light"`.
39
39
  */
40
40
  highlighter?: {
41
+ /**
42
+ * The available themes.
43
+ * The default shiki themes are always included.
44
+ */
41
45
  themes: (ThemeInput | StringLiteralUnion<BundledTheme, string>)[];
46
+ /**
47
+ * What the default theme should be.
48
+ * @default "The first theme in the array"
49
+ */
42
50
  defaultTheme?: string | StringLiteralUnion<BundledTheme, string>;
51
+ /**
52
+ * Custom transformers.
53
+ *
54
+ * These Shiki's default transformers are always included:
55
+ * - transformerNotationHighlight
56
+ * - transformerNotationDiff
57
+ * - transformerNotationErrorLevel
58
+ */
43
59
  transformers?: ShikiTransformer[];
60
+ /**
61
+ * If comments should be filtered.
62
+ * - Passing `true` removes all comments
63
+ * - While `string[]` acts as a filter - removing comments that `include` any of these strings in them
64
+ * - `false` keeps all comments
65
+ *
66
+ * @default ["prettier-ignore"]
67
+ */
68
+ removeComments?: boolean | string[];
69
+ /**
70
+ * If any postprocessing should be done.
71
+ * The element is a JSDOM HTMLPreElement.
72
+ */
44
73
  postprocess?: (pre: HTMLPreElement) => void;
45
74
  };
46
75
  }
@@ -50,6 +79,7 @@ export interface ResolvedOptions extends Omit<Options, "highlighter"> {
50
79
  themesInput: Record<string, string>;
51
80
  defaultTheme: string;
52
81
  transformers: ShikiTransformer[];
82
+ removeComments: boolean | string[];
53
83
  postprocess?: (pre: HTMLPreElement) => void;
54
84
  };
55
85
  }
@@ -44,12 +44,14 @@ export default () => {
44
44
 
45
45
  import highlightedSource from "${id}?highlight";
46
46
  import highlightedCssSource from "${id}?highlight&lang=css";
47
+ import highlightedStylelessSource from "${id}?highlight&styleless";
47
48
 
48
49
  export default defineComponent((props) => {
49
50
  return () => h(SandboxIframe, {
50
51
  id: "${toParamId(id)}",
51
52
  highlightedSource,
52
53
  highlightedCssSource,
54
+ highlightedStylelessSource,
53
55
  });
54
56
  });
55
57
  `.trim();
@@ -10,6 +10,9 @@ export declare const viteConfig: {
10
10
  plugins: Plugin<any>[];
11
11
  server: {
12
12
  port: number;
13
+ fs: {
14
+ allow: string[];
15
+ };
13
16
  };
14
17
  preview: {
15
18
  port: number;
@@ -1,6 +1,6 @@
1
1
  import { join } from "node:path";
2
2
  import { loadConfigFromFile } from "vite";
3
- import { docs, ui, output } from "./files.js";
3
+ import { docs, ui, output, root } from "./files.js";
4
4
  import { plugins } from "./plugins/plugins.js";
5
5
  export const getUserViteConfig = async (command) => {
6
6
  const userConfigFile = await loadConfigFromFile({
@@ -39,7 +39,12 @@ const getUserPlugins = async (userViteConfig) => {
39
39
  VuePlugin({
40
40
  ...vuePluginApi.options,
41
41
  include: [/\.vue$/, /\.md$/],
42
- exclude: [/\.vue\?meta$/, /\.vue\?highlight$/, /\.vue\?highlight&lang=css$/],
42
+ exclude: [
43
+ /\.vue\?meta$/,
44
+ /\.vue\?highlight$/,
45
+ /\.vue\?highlight&lang=css$/,
46
+ /\.vue\?highlight&styleless$/,
47
+ ],
43
48
  }),
44
49
  ...resolvedUserPlugins.filter((i) => i.name !== "vite:vue"),
45
50
  ];
@@ -49,6 +54,9 @@ export const viteConfig = {
49
54
  plugins: plugins(),
50
55
  server: {
51
56
  port: 1998,
57
+ fs: {
58
+ allow: [ui, root],
59
+ },
52
60
  },
53
61
  preview: {
54
62
  port: 1996,
@@ -1 +1 @@
1
- import{computed as e,createBlock as t,createCommentVNode as n,createElementBlock as r,defineComponent as i,mergeProps as a,onBeforeMount as o,openBlock as s,shallowRef as c,unref as l}from"vue";import u from"do11y:options";var d=[`src`],f=i({__name:`SandboxIframe`,props:{id:{},url:{},highlightedSource:{},highlightedCssSource:{},passedProps:{}},setup(n){let i=n,f=e(()=>`/sandbox?id=${i.id}`),p=c();return o(async()=>{p.value=(await u.SandboxIframe?.())?.default}),(e,i)=>p.value?(s(),t(l(p),a({key:0,id:n.id,url:f.value,"highlighted-source":n.highlightedSource,"highlighted-css-source":n.highlightedCssSource},n.passedProps),null,16,[`id`,`url`,`highlighted-source`,`highlighted-css-source`])):(s(),r(`iframe`,{key:1,src:f.value},null,8,d))}});export{f as default};
1
+ import{computed as e,createBlock as t,createCommentVNode as n,createElementBlock as r,defineComponent as i,mergeProps as a,onBeforeMount as o,openBlock as s,shallowRef as c,unref as l}from"vue";import u from"do11y:options";var d=[`src`],f=i({__name:`SandboxIframe`,props:{id:{},url:{},highlightedSource:{},highlightedStylelessSource:{},highlightedCssSource:{},passedProps:{}},setup(n){let i=n,f=e(()=>`/sandbox?id=${i.id}`),p=c();return o(async()=>{p.value=(await u.SandboxIframe?.())?.default}),(e,i)=>p.value?(s(),t(l(p),a({key:0,id:n.id,url:f.value,"highlighted-source":n.highlightedSource,"highlighted-css-source":n.highlightedCssSource,"highlighted-styleless-source":n.highlightedStylelessSource},n.passedProps),null,16,[`id`,`url`,`highlighted-source`,`highlighted-css-source`,`highlighted-styleless-source`])):(s(),r(`iframe`,{key:1,src:f.value},null,8,d))}});export{f as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "do11y",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "description": "A bare-bones tool to document Vue components.",
5
5
  "keywords": [
6
6
  "docs-generator",