vitepress-plugin-field 0.1.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 pengzhanbo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,177 @@
1
+ # vitepress-plugin-field
2
+
3
+ Render structured API fields and properties documentation in your VitePress site.
4
+
5
+ 在 VitePress 中渲染结构化的 API 字段/属性文档。
6
+
7
+ ## Usage
8
+
9
+ ### With Vitepress-tuck
10
+
11
+ **Installation:**
12
+
13
+ ```bash
14
+ # npm
15
+ npm install -D vitepress-tuck vitepress-plugin-field
16
+ # pnpm
17
+ pnpm add -D vitepress-tuck vitepress-plugin-field
18
+ # yarn
19
+ yarn add -D vitepress-tuck vitepress-plugin-field
20
+ ```
21
+
22
+ **Configuration:**
23
+
24
+ ```ts
25
+ // .vitepress/config.ts
26
+ import field from 'vitepress-plugin-field'
27
+ import { defineConfig } from 'vitepress-tuck'
28
+
29
+ export default defineConfig({
30
+ plugins: [field()],
31
+ })
32
+ ```
33
+
34
+ ### With Vitepress
35
+
36
+ **Installation:**
37
+
38
+ ```bash
39
+ # npm
40
+ npm install -D vitepress-plugin-field
41
+ # pnpm
42
+ pnpm add -D vitepress-plugin-field
43
+ # yarn
44
+ yarn add -D vitepress-plugin-field
45
+ ```
46
+
47
+ **Configuration:**
48
+
49
+ ```ts
50
+ // .vitepress/config.ts
51
+ import { defineConfig } from 'vitepress'
52
+ import { fieldMarkdownPlugin } from 'vitepress-plugin-field'
53
+
54
+ export default defineConfig({
55
+ markdown: {
56
+ config: (md) => {
57
+ md.use(fieldMarkdownPlugin)
58
+ },
59
+ },
60
+ })
61
+ ```
62
+
63
+ ```ts
64
+ // .vitepress/theme/index.ts
65
+ import { enhanceAppWithField } from 'vitepress-plugin-field/client'
66
+ import type { Theme } from 'vitepress'
67
+ import DefaultTheme from 'vitepress/theme'
68
+
69
+ export default {
70
+ extends: DefaultTheme,
71
+ enhanceApp(ctx) {
72
+ enhanceAppWithField(ctx)
73
+ },
74
+ } satisfies Theme
75
+ ```
76
+
77
+ ## Syntax
78
+
79
+ Use `::: field` containers to document API fields and properties, with JSDoc-style tags for metadata.
80
+
81
+ ### Basic Field
82
+
83
+ ```md
84
+ ::: field count
85
+ @type Number
86
+ @default 0
87
+
88
+ Count value.
89
+ :::
90
+ ```
91
+
92
+ ### Field with Tags
93
+
94
+ Supported tags: `@name`, `@type`, `@default`, `@required`, `@deprecated`, `@optional`, `@description`.
95
+
96
+ ```md
97
+ ::: field userName
98
+ @type String
99
+ @required
100
+ User's unique identifier name.
101
+ :::
102
+
103
+ ::: field email
104
+ @type String
105
+ @optional
106
+ @default example@mail.com
107
+ Contact email.
108
+ :::
109
+
110
+ ::: field oldField
111
+ @type String
112
+ @deprecated
113
+ This field is deprecated. Please use a new field instead.
114
+ :::
115
+ ```
116
+
117
+ ### Field Group
118
+
119
+ Use `::: field-group` to group related fields together.
120
+
121
+ ```md
122
+ ::: field-group
123
+
124
+ ::: field id
125
+ @type Number
126
+ @required
127
+ Unique identifier.
128
+ :::
129
+
130
+ ::: field name
131
+ @type String
132
+ @optional
133
+ Display name.
134
+ :::
135
+
136
+ ::: field createdAt
137
+ @type Date
138
+ @default Date.now()
139
+ Created at.
140
+ :::
141
+
142
+ :::
143
+ ```
144
+
145
+ ### Explicit Description
146
+
147
+ Use `@description` tag for explicit description text. Any non-tag line also feeds into description.
148
+
149
+ ```md
150
+ ::: field count
151
+ @description This field represents the total number of active users in the system.
152
+ @type Number
153
+ @default 0
154
+ :::
155
+ ```
156
+
157
+ ### Custom Field Name
158
+
159
+ Override the field name via `@name` tag.
160
+
161
+ ```md
162
+ ::: field count
163
+ @name count
164
+ @type Number
165
+ @default 0
166
+ :::
167
+ ```
168
+
169
+ ## Component
170
+
171
+ The `VPField` component is also available for direct use:
172
+
173
+ ```vue
174
+ <VPField name="count" type="Number" required>
175
+ <p>User count.</p>
176
+ </VPField>
177
+ ```
@@ -0,0 +1,30 @@
1
+ import { EnhanceAppContext } from "vitepress";
2
+
3
+ //#region src/client/VPField.vue.d.ts
4
+ type __VLS_Props = {
5
+ name: string;
6
+ type?: string;
7
+ required?: boolean;
8
+ optional?: boolean;
9
+ deprecated?: boolean;
10
+ defaultValue?: string;
11
+ };
12
+ declare var __VLS_1: {};
13
+ type __VLS_Slots = {} & {
14
+ default?: (props: typeof __VLS_1) => any;
15
+ };
16
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
17
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
18
+ declare const _default: typeof __VLS_export;
19
+ type __VLS_WithSlots<T, S> = T & {
20
+ new (): {
21
+ $slots: S;
22
+ };
23
+ };
24
+ //#endregion
25
+ //#region src/client/index.d.ts
26
+ declare function enhanceAppWithField({
27
+ app
28
+ }: EnhanceAppContext): void;
29
+ //#endregion
30
+ export { _default as VPField, enhanceAppWithField };
@@ -0,0 +1,64 @@
1
+ import "../style.css";
2
+ import { computed, createCommentVNode, createElementBlock, createElementVNode, defineComponent, normalizeClass, openBlock, renderSlot, toDisplayString } from "vue";
3
+ //#region src/client/VPField.vue
4
+ const _hoisted_1 = { class: "field-meta" };
5
+ const _hoisted_2 = { class: "name" };
6
+ const _hoisted_3 = {
7
+ key: 1,
8
+ class: "deprecated"
9
+ };
10
+ const _hoisted_4 = {
11
+ key: 2,
12
+ class: "type"
13
+ };
14
+ const _hoisted_5 = {
15
+ key: 0,
16
+ class: "default-value"
17
+ };
18
+ const _hoisted_6 = {
19
+ key: 1,
20
+ class: "description"
21
+ };
22
+ const _sfc_main = /* @__PURE__ */ defineComponent({
23
+ __name: "VPField",
24
+ props: {
25
+ name: {},
26
+ type: {},
27
+ required: { type: Boolean },
28
+ optional: { type: Boolean },
29
+ deprecated: { type: Boolean },
30
+ defaultValue: {}
31
+ },
32
+ setup(__props) {
33
+ const badge = computed(() => __props.required ? "Required" : __props.optional ? "Optional" : "");
34
+ return (_ctx, _cache) => {
35
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["vp-field", {
36
+ required: __props.required,
37
+ optional: __props.optional,
38
+ deprecated: __props.deprecated
39
+ }]) }, [
40
+ createElementVNode("p", _hoisted_1, [
41
+ createElementVNode("span", _hoisted_2, toDisplayString(__props.name), 1),
42
+ badge.value ? (openBlock(), createElementBlock("span", {
43
+ key: 0,
44
+ class: normalizeClass({
45
+ required: __props.required,
46
+ optional: __props.optional
47
+ })
48
+ }, toDisplayString(badge.value), 3)) : createCommentVNode("v-if", true),
49
+ __props.deprecated ? (openBlock(), createElementBlock("span", _hoisted_3, "Deprecated")) : createCommentVNode("v-if", true),
50
+ __props.type ? (openBlock(), createElementBlock("span", _hoisted_4, [createElementVNode("code", null, toDisplayString(__props.type), 1)])) : createCommentVNode("v-if", true)
51
+ ]),
52
+ __props.defaultValue ? (openBlock(), createElementBlock("p", _hoisted_5, [createElementVNode("code", null, toDisplayString(__props.defaultValue), 1)])) : createCommentVNode("v-if", true),
53
+ _ctx.$slots.default ? (openBlock(), createElementBlock("div", _hoisted_6, [renderSlot(_ctx.$slots, "default")])) : createCommentVNode("v-if", true)
54
+ ], 2);
55
+ };
56
+ }
57
+ });
58
+ //#endregion
59
+ //#region src/client/index.ts
60
+ function enhanceAppWithField({ app }) {
61
+ app.component("VPField", _sfc_main);
62
+ }
63
+ //#endregion
64
+ export { _sfc_main as VPField, enhanceAppWithField };
@@ -0,0 +1,30 @@
1
+ import { EnhanceAppContext } from "vitepress";
2
+
3
+ //#region src/client/VPField.vue.d.ts
4
+ type __VLS_Props = {
5
+ name: string;
6
+ type?: string;
7
+ required?: boolean;
8
+ optional?: boolean;
9
+ deprecated?: boolean;
10
+ defaultValue?: string;
11
+ };
12
+ declare var __VLS_1: {};
13
+ type __VLS_Slots = {} & {
14
+ default?: (props: typeof __VLS_1) => any;
15
+ };
16
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
17
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
18
+ declare const _default: typeof __VLS_export;
19
+ type __VLS_WithSlots<T, S> = T & {
20
+ new (): {
21
+ $slots: S;
22
+ };
23
+ };
24
+ //#endregion
25
+ //#region src/client/index.d.ts
26
+ declare function enhanceAppWithField({
27
+ app
28
+ }: EnhanceAppContext): void;
29
+ //#endregion
30
+ export { _default as VPField, enhanceAppWithField };
@@ -0,0 +1,56 @@
1
+ import { computed, defineComponent, mergeProps, useSSRContext } from "vue";
2
+ import { ssrInterpolate, ssrRenderAttrs, ssrRenderClass, ssrRenderSlot } from "vue/server-renderer";
3
+ //#region src/client/VPField.vue
4
+ const _sfc_main = /* @__PURE__ */ defineComponent({
5
+ __name: "VPField",
6
+ __ssrInlineRender: true,
7
+ props: {
8
+ name: {},
9
+ type: {},
10
+ required: { type: Boolean },
11
+ optional: { type: Boolean },
12
+ deprecated: { type: Boolean },
13
+ defaultValue: {}
14
+ },
15
+ setup(__props) {
16
+ const badge = computed(() => __props.required ? "Required" : __props.optional ? "Optional" : "");
17
+ return (_ctx, _push, _parent, _attrs) => {
18
+ _push(`<div${ssrRenderAttrs(mergeProps({ class: ["vp-field", {
19
+ required: __props.required,
20
+ optional: __props.optional,
21
+ deprecated: __props.deprecated
22
+ }] }, _attrs))}><p class="field-meta"><span class="name">${ssrInterpolate(__props.name)}</span>`);
23
+ if (badge.value) _push(`<span class="${ssrRenderClass({
24
+ required: __props.required,
25
+ optional: __props.optional
26
+ })}">${ssrInterpolate(badge.value)}</span>`);
27
+ else _push(`<!---->`);
28
+ if (__props.deprecated) _push(`<span class="deprecated">Deprecated</span>`);
29
+ else _push(`<!---->`);
30
+ if (__props.type) _push(`<span class="type"><code>${ssrInterpolate(__props.type)}</code></span>`);
31
+ else _push(`<!---->`);
32
+ _push(`</p>`);
33
+ if (__props.defaultValue) _push(`<p class="default-value"><code>${ssrInterpolate(__props.defaultValue)}</code></p>`);
34
+ else _push(`<!---->`);
35
+ if (_ctx.$slots.default) {
36
+ _push(`<div class="description">`);
37
+ ssrRenderSlot(_ctx.$slots, "default", {}, null, _push, _parent);
38
+ _push(`</div>`);
39
+ } else _push(`<!---->`);
40
+ _push(`</div>`);
41
+ };
42
+ }
43
+ });
44
+ const _sfc_setup = _sfc_main.setup;
45
+ _sfc_main.setup = (props, ctx) => {
46
+ const ssrContext = useSSRContext();
47
+ (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("src/client/VPField.vue");
48
+ return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
49
+ };
50
+ //#endregion
51
+ //#region src/client/index.ts
52
+ function enhanceAppWithField({ app }) {
53
+ app.component("VPField", _sfc_main);
54
+ }
55
+ //#endregion
56
+ export { _sfc_main as VPField, enhanceAppWithField };
@@ -0,0 +1,77 @@
1
+ .vp-field {
2
+ width: 100%;
3
+ margin: 16px 0;
4
+ transition: border-color 0.25s ease;
5
+ }
6
+
7
+ .vp-field + .vp-field {
8
+ padding-top: 8px;
9
+ border-top: solid 1px var(--vp-c-divider);
10
+ }
11
+
12
+ .vp-field .field-meta {
13
+ display: flex;
14
+ gap: 8px;
15
+ align-items: flex-start;
16
+ margin: 8px 0;
17
+ }
18
+
19
+ .vp-field .field-meta .name {
20
+ font-size: 18px;
21
+ font-weight: 500;
22
+ }
23
+
24
+ .vp-field.deprecated .field-meta .name {
25
+ text-decoration: line-through;
26
+ }
27
+
28
+ .vp-field .field-meta .required,
29
+ .vp-field .field-meta .optional,
30
+ .vp-field .field-meta .deprecated {
31
+ display: inline-block;
32
+ padding: 2px 8px;
33
+ font-size: 12px;
34
+ font-style: italic;
35
+ line-height: 1;
36
+ border-radius: 8px;
37
+ }
38
+
39
+ .vp-field .field-meta .required {
40
+ color: var(--vp-c-success-2);
41
+ border: solid 1px var(--vp-c-success-2);
42
+ }
43
+
44
+ .vp-field .field-meta .optional {
45
+ color: var(--vp-c-text-3);
46
+ border: solid 1px var(--vp-c-divider);
47
+ }
48
+
49
+ .vp-field .field-meta .deprecated {
50
+ color: var(--vp-c-danger-2);
51
+ border: solid 1px var(--vp-c-danger-2);
52
+ }
53
+
54
+ .vp-field .field-meta .type {
55
+ flex: 1 2;
56
+ text-align: right;
57
+ }
58
+
59
+ .vp-field .default-value {
60
+ margin: 0;
61
+ font-size: 14px;
62
+ line-height: 1.7;
63
+ transform: translateY(-4px);
64
+ }
65
+
66
+ .vp-field .description :where(p, ul, ol) {
67
+ margin: 8px 0;
68
+ line-height: 24px;
69
+ color: var(--vp-c-text-2);
70
+ }
71
+
72
+ .vp-field-group {
73
+ padding: 0 20px;
74
+ margin: 16px 0;
75
+ border: solid 1px var(--vp-c-divider);
76
+ border-radius: 6px;
77
+ }
@@ -0,0 +1,91 @@
1
+ import { PluginSimple } from "markdown-it";
2
+
3
+ //#region src/node/fieldPlugin.d.ts
4
+ /**
5
+ * Parsed result from a `::: field` container block.
6
+ *
7
+ * 字段对象 — 解析自 `::: field` 容器块的结构化结果
8
+ */
9
+ interface FieldObject {
10
+ /**
11
+ * Field name — defaults to `info`, overridable via `@name`
12
+ *
13
+ * 字段名称 — 默认从 `info` 中获取,可通过 `@name` 覆盖
14
+ */
15
+ name: string;
16
+ /**
17
+ * `@type` value, undefined if not set
18
+ *
19
+ * 类型注解 — 如果未设置则为 `undefined`
20
+ */
21
+ type?: string;
22
+ /**
23
+ * `@default` value, preserved as-is
24
+ *
25
+ * 默认值 — 保持原样
26
+ */
27
+ default?: string;
28
+ /**
29
+ * Whether `@required` is present
30
+ *
31
+ * 是否为必填项 — 是否在 `@required` 标签中
32
+ */
33
+ required?: boolean;
34
+ /**
35
+ * Whether `@deprecated` is present
36
+ *
37
+ * 是否为已弃用项 — 是否在 `@deprecated` 标签中
38
+ */
39
+ deprecated?: boolean;
40
+ /**
41
+ * Whether `@optional` is present
42
+ *
43
+ * 是否为可选项 — 是否在 `@optional` 标签中
44
+ */
45
+ optional?: boolean;
46
+ /**
47
+ * Description text, may span multiple lines joined by `\n`
48
+ *
49
+ * 描述文本 — 可跨多行,以 `\n` 连接
50
+ */
51
+ description?: string;
52
+ }
53
+ /**
54
+ * Parse the body of a `::: field` container into a structured `FieldObject`.
55
+ *
56
+ * Supports a JSDoc-style tag syntax:
57
+ * - `@name` — override the field name (derived from `info` by default)
58
+ * - `@type` — type annotation
59
+ * - `@default` — default value
60
+ * - `@required` — mark as required (boolean flag)
61
+ * - `@deprecated` — mark as deprecated (boolean flag)
62
+ * - `@optional` — mark as optional (boolean flag)
63
+ * - `@description` — explicit description; any non-tag line also feeds into description
64
+ *
65
+ * Unknown `@`-prefixed tags are treated as description text.
66
+ * Empty lines are ignored and never interrupt a description paragraph.
67
+ *
68
+ * 将 `::: field` 容器的正文解析为结构化的 `FieldObject`。
69
+ *
70
+ * 支持类 JSDoc 的标签语法:
71
+ * - `@name` — 覆盖字段名称(默认从 `info` 派生)
72
+ * - `@type` — 类型注解
73
+ * - `@default` — 默认值
74
+ * - `@required` — 标记为必需(布尔标志)
75
+ * - `@deprecated` — 标记为已弃用(布尔标志)
76
+ * - `@optional` — 标记为可选(布尔标志)
77
+ * - `@description` — 显式描述;任何非标签行也会被纳入描述
78
+ *
79
+ * 未知的以 `@` 开头的标签将被视为描述文本。
80
+ * 空行会被忽略,且不会中断描述段落。
81
+ *
82
+ * @param content Raw text inside the `:::` container
83
+ * @param info Text after `::: field` on the opening line (the field name)
84
+ */
85
+ declare function parseFieldContent(content: string, info: string): FieldObject;
86
+ declare const fieldMarkdownPlugin: PluginSimple;
87
+ //#endregion
88
+ //#region src/node/index.d.ts
89
+ declare const _default: (option?: unknown) => import("vitepress-tuck").VitepressPlugin;
90
+ //#endregion
91
+ export { type FieldObject, _default as default, fieldMarkdownPlugin, parseFieldContent };
@@ -0,0 +1,124 @@
1
+ import { definePlugin } from "vitepress-tuck";
2
+ import { isUndefined } from "@pengzhanbo/utils";
3
+ import { createContainerPlugin, createContainerSyntaxPlugin, stringifyAttrs } from "vitepress-plugin-toolkit";
4
+ //#region src/node/fieldPlugin.ts
5
+ /** Tags that carry structured meaning; everything else is description text. */
6
+ const KNOWN_TAGS = new Set([
7
+ "name",
8
+ "type",
9
+ "default",
10
+ "required",
11
+ "deprecated",
12
+ "optional",
13
+ "description"
14
+ ]);
15
+ /**
16
+ * Parse the body of a `::: field` container into a structured `FieldObject`.
17
+ *
18
+ * Supports a JSDoc-style tag syntax:
19
+ * - `@name` — override the field name (derived from `info` by default)
20
+ * - `@type` — type annotation
21
+ * - `@default` — default value
22
+ * - `@required` — mark as required (boolean flag)
23
+ * - `@deprecated` — mark as deprecated (boolean flag)
24
+ * - `@optional` — mark as optional (boolean flag)
25
+ * - `@description` — explicit description; any non-tag line also feeds into description
26
+ *
27
+ * Unknown `@`-prefixed tags are treated as description text.
28
+ * Empty lines are ignored and never interrupt a description paragraph.
29
+ *
30
+ * 将 `::: field` 容器的正文解析为结构化的 `FieldObject`。
31
+ *
32
+ * 支持类 JSDoc 的标签语法:
33
+ * - `@name` — 覆盖字段名称(默认从 `info` 派生)
34
+ * - `@type` — 类型注解
35
+ * - `@default` — 默认值
36
+ * - `@required` — 标记为必需(布尔标志)
37
+ * - `@deprecated` — 标记为已弃用(布尔标志)
38
+ * - `@optional` — 标记为可选(布尔标志)
39
+ * - `@description` — 显式描述;任何非标签行也会被纳入描述
40
+ *
41
+ * 未知的以 `@` 开头的标签将被视为描述文本。
42
+ * 空行会被忽略,且不会中断描述段落。
43
+ *
44
+ * @param content Raw text inside the `:::` container
45
+ * @param info Text after `::: field` on the opening line (the field name)
46
+ */
47
+ function parseFieldContent(content, info) {
48
+ const lines = content.split("\n");
49
+ const result = {
50
+ name: info.trim(),
51
+ description: ""
52
+ };
53
+ /** Accumulates the current description paragraph. */
54
+ let currentDesc = "";
55
+ /** Completed description segments, joined with `\n` at the end. */
56
+ const descriptions = [];
57
+ function flushDesc() {
58
+ if (currentDesc) {
59
+ descriptions.push(currentDesc);
60
+ currentDesc = "";
61
+ }
62
+ }
63
+ for (const rawLine of lines) {
64
+ const line = rawLine.trim();
65
+ if (line.startsWith("@")) {
66
+ const spaceIdx = line.indexOf(" ");
67
+ let tag;
68
+ let rest;
69
+ if (spaceIdx === -1) {
70
+ tag = line.slice(1);
71
+ rest = "";
72
+ } else {
73
+ tag = line.slice(1, spaceIdx).toLowerCase();
74
+ rest = line.slice(spaceIdx + 1).trim();
75
+ }
76
+ if (KNOWN_TAGS.has(tag)) {
77
+ flushDesc();
78
+ switch (tag) {
79
+ case "name":
80
+ case "type":
81
+ case "default":
82
+ rest && (result[tag] = rest);
83
+ break;
84
+ case "required":
85
+ case "deprecated":
86
+ case "optional":
87
+ result[tag] = true;
88
+ break;
89
+ case "description":
90
+ currentDesc = rest;
91
+ break;
92
+ }
93
+ } else {
94
+ if (currentDesc) currentDesc += "\n";
95
+ currentDesc += line;
96
+ }
97
+ } else {
98
+ if (currentDesc) currentDesc += "\n";
99
+ currentDesc += line;
100
+ }
101
+ }
102
+ flushDesc();
103
+ result.description = descriptions.join("\n");
104
+ return result;
105
+ }
106
+ const fieldMarkdownPlugin = (md) => {
107
+ createContainerPlugin(md, "field-group", { before: () => "<div class=\"vp-field-group\">" });
108
+ createContainerSyntaxPlugin(md, "field", (tokens, idx, _, env) => {
109
+ const { info, content } = tokens[idx];
110
+ const { description, type, default: defaultValue, ...props } = parseFieldContent(content, info);
111
+ return `<VPField${stringifyAttrs(props)}${isUndefined(type) ? "" : ` type="${type}"`}${isUndefined(defaultValue) ? "" : ` default-value="${defaultValue}"`}>${description ? md.render(description, env) : ""}</VPField>`;
112
+ });
113
+ };
114
+ //#endregion
115
+ //#region src/node/index.ts
116
+ var node_default = definePlugin(() => ({
117
+ name: "vitepress-plugin-field",
118
+ client: { enhance: "enhanceAppWithField" },
119
+ markdown: { config(md) {
120
+ md.use(fieldMarkdownPlugin);
121
+ } }
122
+ }));
123
+ //#endregion
124
+ export { node_default as default, fieldMarkdownPlugin, parseFieldContent };
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "vitepress-plugin-field",
3
+ "type": "module",
4
+ "version": "0.1.1",
5
+ "description": "Render file tree structure in your VitePress site.",
6
+ "author": "pengzhanbo <q942450674@outlook.com> (https://github.com/pengzhanbo/)",
7
+ "license": "MIT",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/pengzhanbo/vitepress-tuck.git",
11
+ "directory": "packages/plugin-field"
12
+ },
13
+ "keywords": [
14
+ "vitepress",
15
+ "vitepress-plugin",
16
+ "field"
17
+ ],
18
+ "exports": {
19
+ ".": "./dist/node/index.js",
20
+ "./client": {
21
+ "browser": "./dist/client/browser/index.js",
22
+ "default": "./dist/client/ssr/index.js"
23
+ },
24
+ "./style.css": "./dist/client/style.css"
25
+ },
26
+ "module": "./dist/node/index.js",
27
+ "types": "./dist/node/index.d.ts",
28
+ "files": [
29
+ "dist"
30
+ ],
31
+ "peerDependencies": {
32
+ "vitepress": "^1.6.4 || ^2.0.0-alpha.17",
33
+ "vue": "^3.5.0"
34
+ },
35
+ "dependencies": {
36
+ "@pengzhanbo/utils": "^3.7.3",
37
+ "vitepress-plugin-toolkit": "0.1.1",
38
+ "vitepress-tuck": "0.1.1"
39
+ },
40
+ "publishConfig": {
41
+ "access": "public"
42
+ },
43
+ "scripts": {
44
+ "clean": "rimraf --glob ./dist",
45
+ "dev": "pnpm '/(tsdown|copy):watch/'",
46
+ "build": "pnpm tsdown && pnpm copy",
47
+ "copy": "cpx \"src/**/*.css\" dist",
48
+ "copy:watch": "pnpm copy -w",
49
+ "tsdown": "tsdown --config-loader unrun",
50
+ "tsdown:watch": "pnpm tsdown -w"
51
+ }
52
+ }