docusaurus-theme-openapi-docs 4.2.0 → 4.3.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.
@@ -58,13 +58,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
58
58
  const react_1 = __importStar(require("react"));
59
59
  const BrowserOnly_1 = __importDefault(require("@docusaurus/BrowserOnly"));
60
60
  const Details_1 = __importDefault(require("@theme/Details"));
61
+ const Markdown_1 = __importDefault(require("@theme/Markdown"));
61
62
  const MimeTabs_1 = __importDefault(require("@theme/MimeTabs")); // Assume these components exist
62
63
  const ResponseExamples_1 = require("@theme/ResponseExamples");
63
64
  const Schema_1 = __importDefault(require("@theme/Schema"));
64
65
  const SchemaTabs_1 = __importDefault(require("@theme/SchemaTabs"));
65
66
  const SkeletonLoader_1 = __importDefault(require("@theme/SkeletonLoader"));
66
67
  const TabItem_1 = __importDefault(require("@theme/TabItem"));
67
- const createDescription_1 = require("docusaurus-plugin-openapi-docs/lib/markdown/createDescription");
68
68
  const ResponseSchemaComponent = ({ title, body, style }) => {
69
69
  if (
70
70
  body === undefined ||
@@ -143,7 +143,9 @@ const ResponseSchemaComponent = ({ title, body, style }) => {
143
143
  {
144
144
  style: { marginTop: "1rem", marginBottom: "1rem" },
145
145
  },
146
- (0, createDescription_1.createDescription)(
146
+ react_1.default.createElement(
147
+ Markdown_1.default,
148
+ null,
147
149
  body.description
148
150
  )
149
151
  )
@@ -17,17 +17,15 @@ const Details_1 = __importDefault(require("@theme/Details"));
17
17
  const DiscriminatorTabs_1 = __importDefault(
18
18
  require("@theme/DiscriminatorTabs")
19
19
  );
20
+ const Markdown_1 = __importDefault(require("@theme/Markdown"));
20
21
  const SchemaItem_1 = __importDefault(require("@theme/SchemaItem"));
21
22
  const SchemaTabs_1 = __importDefault(require("@theme/SchemaTabs"));
22
23
  const TabItem_1 = __importDefault(require("@theme/TabItem"));
23
24
  // eslint-disable-next-line import/no-extraneous-dependencies
24
25
  const allof_merge_1 = require("allof-merge");
25
26
  const clsx_1 = __importDefault(require("clsx"));
26
- const createDescription_1 = require("docusaurus-plugin-openapi-docs/lib/markdown/createDescription");
27
27
  const schema_1 = require("docusaurus-plugin-openapi-docs/lib/markdown/schema");
28
28
  const isEmpty_1 = __importDefault(require("lodash/isEmpty"));
29
- const react_markdown_1 = __importDefault(require("react-markdown"));
30
- const rehype_raw_1 = __importDefault(require("rehype-raw"));
31
29
  // eslint-disable-next-line import/no-extraneous-dependencies
32
30
  // const jsonSchemaMergeAllOf = require("json-schema-merge-allof");
33
31
  const mergeAllOf = (allOf) => {
@@ -38,14 +36,11 @@ const mergeAllOf = (allOf) => {
38
36
  return mergedSchemas;
39
37
  };
40
38
  // Renders string as markdown, useful for descriptions and qualifiers
41
- const Markdown = ({ text }) => {
39
+ const MarkdownWrapper = ({ text }) => {
42
40
  return react_1.default.createElement(
43
41
  "div",
44
42
  { style: { marginTop: ".5rem", marginBottom: ".5rem" } },
45
- react_1.default.createElement(react_markdown_1.default, {
46
- children: (0, createDescription_1.createDescription)(text),
47
- rehypePlugins: [rehype_raw_1.default],
48
- })
43
+ react_1.default.createElement(Markdown_1.default, null, text)
49
44
  );
50
45
  };
51
46
  const Summary = ({ name, schemaName, schema, required }) => {
@@ -276,11 +271,11 @@ const PropertyDiscriminator = ({
276
271
  "div",
277
272
  { style: { marginLeft: "1rem" } },
278
273
  schema.description &&
279
- react_1.default.createElement(Markdown, {
274
+ react_1.default.createElement(MarkdownWrapper, {
280
275
  text: schema.description,
281
276
  }),
282
277
  (0, schema_1.getQualifierMessage)(discriminator) &&
283
- react_1.default.createElement(Markdown, {
278
+ react_1.default.createElement(MarkdownWrapper, {
284
279
  text: (0, schema_1.getQualifierMessage)(discriminator),
285
280
  })
286
281
  ),
@@ -321,7 +316,10 @@ const PropertyDiscriminator = ({
321
316
  const DiscriminatorNode = ({ discriminator, schema, schemaType }) => {
322
317
  let discriminatedSchemas = {};
323
318
  let inferredMapping = {};
324
- const discriminatorProperty = schema.properties[discriminator.propertyName];
319
+ // default to empty object if no parent-level properties exist
320
+ const discriminatorProperty = schema.properties
321
+ ? schema.properties[discriminator.propertyName]
322
+ : {};
325
323
  if (schema.allOf) {
326
324
  const mergedSchemas = mergeAllOf(schema);
327
325
  if (mergedSchemas.oneOf || mergedSchemas.anyOf) {
@@ -347,15 +345,23 @@ const DiscriminatorNode = ({ discriminator, schema, schemaType }) => {
347
345
  }
348
346
  const subProperties = subSchema.properties || mergedSubSchema.properties;
349
347
  if (subProperties[discriminator.propertyName]) {
350
- schema.properties[discriminator.propertyName] = {
351
- ...schema.properties[discriminator.propertyName],
352
- ...subProperties[discriminator.propertyName],
353
- };
354
- if (subSchema.required && !schema.required) {
355
- schema.required = subSchema.required;
348
+ if (schema.properties) {
349
+ schema.properties[discriminator.propertyName] = {
350
+ ...schema.properties[discriminator.propertyName],
351
+ ...subProperties[discriminator.propertyName],
352
+ };
353
+ if (subSchema.required && !schema.required) {
354
+ schema.required = subSchema.required;
355
+ }
356
+ // Avoid duplicating property
357
+ delete subProperties[discriminator.propertyName];
358
+ } else {
359
+ schema.properties = {};
360
+ schema.properties[discriminator.propertyName] =
361
+ subProperties[discriminator.propertyName];
362
+ // Avoid duplicating property
363
+ delete subProperties[discriminator.propertyName];
356
364
  }
357
- // Avoid duplicating property
358
- delete subProperties[discriminator.propertyName];
359
365
  }
360
366
  });
361
367
  const name = discriminator.propertyName;
@@ -460,9 +466,11 @@ const SchemaNodeDetails = ({
460
466
  "div",
461
467
  { style: { marginLeft: "1rem" } },
462
468
  schema.description &&
463
- react_1.default.createElement(Markdown, { text: schema.description }),
469
+ react_1.default.createElement(MarkdownWrapper, {
470
+ text: schema.description,
471
+ }),
464
472
  (0, schema_1.getQualifierMessage)(schema) &&
465
- react_1.default.createElement(Markdown, {
473
+ react_1.default.createElement(MarkdownWrapper, {
466
474
  text: (0, schema_1.getQualifierMessage)(schema),
467
475
  }),
468
476
  react_1.default.createElement(SchemaNode, {
@@ -12,12 +12,8 @@ var __importDefault =
12
12
  };
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
14
  const react_1 = __importDefault(require("react"));
15
- const CodeBlock_1 = __importDefault(require("@theme/CodeBlock"));
15
+ const Markdown_1 = __importDefault(require("@theme/Markdown"));
16
16
  const clsx_1 = __importDefault(require("clsx"));
17
- const react_markdown_1 = __importDefault(require("react-markdown"));
18
- const rehype_raw_1 = __importDefault(require("rehype-raw"));
19
- const remark_gfm_1 = __importDefault(require("remark-gfm"));
20
- const createDescription_1 = require("../../markdown/createDescription");
21
17
  const utils_1 = require("../../markdown/utils");
22
18
  const transformEnumDescriptions = (enumDescriptions) => {
23
19
  if (enumDescriptions) {
@@ -91,11 +87,7 @@ function SchemaItem(props) {
91
87
  return react_1.default.createElement(
92
88
  "div",
93
89
  { style: { marginTop: ".5rem" } },
94
- react_1.default.createElement(react_markdown_1.default, {
95
- remarkPlugins: [remark_gfm_1.default],
96
- rehypePlugins: [rehype_raw_1.default],
97
- children: value,
98
- })
90
+ react_1.default.createElement(Markdown_1.default, null, value)
99
91
  );
100
92
  }
101
93
  );
@@ -103,43 +95,18 @@ function SchemaItem(props) {
103
95
  schemaDescription,
104
96
  (description) =>
105
97
  react_1.default.createElement(
106
- "div",
98
+ react_1.default.Fragment,
107
99
  null,
108
- react_1.default.createElement(react_markdown_1.default, {
109
- children: (0, createDescription_1.createDescription)(description),
110
- components: {
111
- pre: "div",
112
- code({ node, inline, className, children, ...props }) {
113
- const match = /language-(\w+)/.exec(className || "");
114
- if (inline)
115
- return react_1.default.createElement("code", null, children);
116
- return !inline && match
117
- ? react_1.default.createElement(
118
- CodeBlock_1.default,
119
- { className: className },
120
- children
121
- )
122
- : react_1.default.createElement(
123
- CodeBlock_1.default,
124
- null,
125
- children
126
- );
127
- },
128
- },
129
- rehypePlugins: [rehype_raw_1.default],
130
- })
100
+ react_1.default.createElement(Markdown_1.default, null, description)
131
101
  )
132
102
  );
133
103
  const renderQualifierMessage = (0, utils_1.guard)(
134
104
  qualifierMessage,
135
105
  (message) =>
136
106
  react_1.default.createElement(
137
- "div",
107
+ react_1.default.Fragment,
138
108
  null,
139
- react_1.default.createElement(react_markdown_1.default, {
140
- children: (0, createDescription_1.createDescription)(message),
141
- rehypePlugins: [rehype_raw_1.default],
142
- })
109
+ react_1.default.createElement(Markdown_1.default, null, message)
143
110
  )
144
111
  );
145
112
  function renderDefaultValue() {
@@ -218,8 +185,7 @@ function SchemaItem(props) {
218
185
  react_1.default.createElement(
219
186
  "span",
220
187
  { className: "openapi-schema__name" },
221
- " ",
222
- schemaName
188
+ Array.isArray(schemaName) ? schemaName.join(" | ") : schemaName
223
189
  ),
224
190
  (nullable || required || deprecated) &&
225
191
  react_1.default.createElement("span", {
@@ -14,10 +14,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
14
14
  const react_1 = __importDefault(require("react"));
15
15
  const ApiTabs_1 = __importDefault(require("@theme/ApiTabs"));
16
16
  const Details_1 = __importDefault(require("@theme/Details"));
17
- const ResponseExamples_1 = require("@theme/ResponseExamples");
17
+ const Markdown_1 = __importDefault(require("@theme/Markdown"));
18
+ const ResponseHeaders_1 = __importDefault(require("@theme/ResponseHeaders"));
18
19
  const ResponseSchema_1 = __importDefault(require("@theme/ResponseSchema"));
19
20
  const TabItem_1 = __importDefault(require("@theme/TabItem"));
20
- const createDescription_1 = require("docusaurus-plugin-openapi-docs/lib/markdown/createDescription");
21
21
  const StatusCodes = ({ label, id, responses }) => {
22
22
  if (!responses) return null;
23
23
  const codes = Object.keys(responses);
@@ -40,7 +40,11 @@ const StatusCodes = ({ label, id, responses }) => {
40
40
  react_1.default.createElement(
41
41
  "div",
42
42
  { style: { marginTop: ".5rem", marginBottom: ".5rem" } },
43
- (0, createDescription_1.createDescription)(response.description)
43
+ react_1.default.createElement(
44
+ Markdown_1.default,
45
+ null,
46
+ response.description
47
+ )
44
48
  )
45
49
  ),
46
50
  responseHeaders &&
@@ -61,10 +65,9 @@ const StatusCodes = ({ label, id, responses }) => {
61
65
  )
62
66
  ),
63
67
  },
64
- react_1.default.createElement(
65
- ResponseExamples_1.ResponseHeaders,
66
- { responseHeaders: responseHeaders }
67
- )
68
+ react_1.default.createElement(ResponseHeaders_1.default, {
69
+ responseHeaders: responseHeaders,
70
+ })
68
71
  ),
69
72
  react_1.default.createElement(ResponseSchema_1.default, {
70
73
  title: "Schema",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "docusaurus-theme-openapi-docs",
3
3
  "description": "OpenAPI theme for Docusaurus.",
4
- "version": "4.2.0",
4
+ "version": "4.3.0",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "openapi",
@@ -28,26 +28,26 @@
28
28
  "watch": "concurrently --names \"lib,lib-next,tsc\" --kill-others \"yarn babel:lib --watch\" \"yarn babel:lib-next --watch\" \"yarn tsc --watch\""
29
29
  },
30
30
  "devDependencies": {
31
+ "@docusaurus/theme-common": "^3.5.0",
31
32
  "@docusaurus/types": "^3.5.0",
32
33
  "@types/crypto-js": "^4.1.0",
33
34
  "@types/file-saver": "^2.0.5",
34
35
  "@types/lodash": "^4.14.176",
35
36
  "concurrently": "^5.2.0",
37
+ "docusaurus-plugin-openapi-docs": "^4.3.0",
38
+ "docusaurus-plugin-sass": "^0.2.3",
36
39
  "eslint-plugin-prettier": "^5.0.1"
37
40
  },
38
41
  "dependencies": {
39
- "@docusaurus/theme-common": "^3.5.0",
40
42
  "@hookform/error-message": "^2.0.1",
41
43
  "@reduxjs/toolkit": "^1.7.1",
42
44
  "allof-merge": "^0.6.6",
43
45
  "clsx": "^1.1.1",
44
46
  "copy-text-to-clipboard": "^3.1.0",
45
47
  "crypto-js": "^4.1.1",
46
- "docusaurus-plugin-openapi-docs": "^4.2.0",
47
- "docusaurus-plugin-sass": "^0.2.3",
48
48
  "file-saver": "^2.0.5",
49
49
  "lodash": "^4.17.20",
50
- "node-polyfill-webpack-plugin": "^2.0.1",
50
+ "node-polyfill-webpack-plugin": "^3.0.0",
51
51
  "postman-code-generators": "^1.10.1",
52
52
  "postman-collection": "^4.4.0",
53
53
  "prism-react-renderer": "^2.3.0",
@@ -61,15 +61,19 @@
61
61
  "remark-gfm": "3.0.1",
62
62
  "sass": "^1.80.4",
63
63
  "sass-loader": "^16.0.2",
64
+ "unist-util-visit": "^5.0.0",
64
65
  "webpack": "^5.61.0",
65
66
  "xml-formatter": "^2.6.1"
66
67
  },
67
68
  "peerDependencies": {
69
+ "@docusaurus/theme-common": "^3.5.0",
70
+ "docusaurus-plugin-openapi-docs": "^4.0.0",
71
+ "docusaurus-plugin-sass": "^0.2.3",
68
72
  "react": "^16.8.4 || ^17.0.0 || ^18.0.0",
69
73
  "react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0"
70
74
  },
71
75
  "engines": {
72
76
  "node": ">=14"
73
77
  },
74
- "gitHead": "e7295a8aa6f3fab5ccc4f8f9ad0e6c33d785aa16"
78
+ "gitHead": "e16e2f912a3da02444d1755b6d350deadd62185f"
75
79
  }
@@ -8,13 +8,6 @@ the background in custom CSS file due bug https://github.com/facebook/docusaurus
8
8
  --docusaurus-highlighted-code-line-bg: rgb(100 100 100);
9
9
  }
10
10
 
11
- .theme-code-block-highlighted-line {
12
- background-color: var(--docusaurus-highlighted-code-line-bg);
13
- display: block;
14
- margin: 0 calc(-1 * var(--ifm-pre-padding));
15
- padding: 0 var(--ifm-pre-padding);
16
- }
17
-
18
11
  .openapi-explorer__code-block-code-line {
19
12
  display: table-row;
20
13
  counter-increment: line-count;
@@ -36,11 +29,6 @@ the background in custom CSS file due bug https://github.com/facebook/docusaurus
36
29
  opacity: 0.4;
37
30
  }
38
31
 
39
- :global(.theme-code-block-highlighted-line)
40
- .openapi-explorer__code-block-code-line-number::before {
41
- opacity: 0.8;
42
- }
43
-
44
32
  .openapi-explorer__code-block-code-line-number {
45
33
  padding-right: var(--ifm-pre-padding);
46
34
  }
@@ -48,6 +48,7 @@ function Authorization() {
48
48
  <FormItem label="Bearer Token" key={a.key + "-bearer"}>
49
49
  <FormTextInput
50
50
  placeholder="Bearer Token"
51
+ password
51
52
  value={data[a.key].token ?? ""}
52
53
  onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
53
54
  const value = e.target.value;
@@ -69,6 +70,7 @@ function Authorization() {
69
70
  <FormItem label="Bearer Token" key={a.key + "-oauth2"}>
70
71
  <FormTextInput
71
72
  placeholder="Bearer Token"
73
+ password
72
74
  value={data[a.key].token ?? ""}
73
75
  onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
74
76
  const value = e.target.value;
@@ -130,6 +132,7 @@ function Authorization() {
130
132
  <FormItem label={`${a.key}`} key={a.key + "-apikey"}>
131
133
  <FormTextInput
132
134
  placeholder={`${a.key}`}
135
+ password
133
136
  value={data[a.key].apiKey ?? ""}
134
137
  onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
135
138
  const value = e.target.value;
@@ -14,6 +14,7 @@ import FormSelect from "@theme/ApiExplorer/FormSelect";
14
14
  import FormTextInput from "@theme/ApiExplorer/FormTextInput";
15
15
  import LiveApp from "@theme/ApiExplorer/LiveEditor";
16
16
  import { useTypedDispatch, useTypedSelector } from "@theme/ApiItem/hooks";
17
+ import Markdown from "@theme/Markdown";
17
18
  import SchemaTabs from "@theme/SchemaTabs";
18
19
  import TabItem from "@theme/TabItem";
19
20
  import { RequestBodyObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
@@ -303,7 +304,7 @@ function Body({
303
304
  </TabItem>
304
305
  {/* @ts-ignore */}
305
306
  <TabItem label="Example" value="example">
306
- {example.summary && <div>{example.summary}</div>}
307
+ {example.summary && <Markdown>{example.summary}</Markdown>}
307
308
  {exampleBody && (
308
309
  <LiveApp
309
310
  action={dispatch}
@@ -341,7 +342,7 @@ function Body({
341
342
  value={example.label}
342
343
  key={example.label}
343
344
  >
344
- {example.summary && <div>{example.summary}</div>}
345
+ {example.summary && <Markdown>{example.summary}</Markdown>}
345
346
  {example.body && (
346
347
  <LiveApp action={dispatch} language={language}>
347
348
  {example.body}
@@ -23,10 +23,13 @@
23
23
 
24
24
  /* Top-Level Details Caret Styling */
25
25
  .openapi-left-panel__container > .openapi-markdown__details > summary::before,
26
- .openapi-markdown__details.mime > summary::before,
27
- .openapi-markdown__details.response > summary::before {
26
+ .openapi-markdown__details.mime > summary::before {
28
27
  top: 0.1rem;
29
28
  }
29
+
30
+ .openapi-markdown__details.response > summary::before {
31
+ top: 0.25rem; /* TODO: figure out why this is necessary */
32
+ }
30
33
  /* End of Top-Level Details Caret Styling */
31
34
 
32
35
  .openapi-markdown__details {
@@ -7,30 +7,172 @@
7
7
 
8
8
  import React from "react";
9
9
 
10
+ import Admonition from "@theme/Admonition";
10
11
  import CodeBlock from "@theme/CodeBlock";
11
12
  import ReactMarkdown from "react-markdown";
12
13
  import rehypeRaw from "rehype-raw";
14
+ import remarkGfm from "remark-gfm";
15
+
16
+ function remarkAdmonition() {
17
+ return (tree) => {
18
+ const openingTagRegex = /^:::(\w+)(?:\[(.*?)\])?\s*$/;
19
+ const closingTagRegex = /^:::\s*$/;
20
+ const textOnlyAdmonition = /^:::(\w+)(?:\[(.*?)\])?\s*([\s\S]*?)\s*:::$/;
21
+
22
+ const nodes = [];
23
+ let bufferedChildren = [];
24
+
25
+ let insideAdmonition = false;
26
+ let type = null;
27
+ let title = null;
28
+
29
+ tree.children.forEach((node) => {
30
+ if (
31
+ node.type === "paragraph" &&
32
+ node.children.length === 1 &&
33
+ node.children[0].type === "text"
34
+ ) {
35
+ const text = node.children[0].value.trim();
36
+ const openingMatch = text.match(openingTagRegex);
37
+ const closingMatch = text.match(closingTagRegex);
38
+ const textOnlyAdmonitionMatch = text.match(textOnlyAdmonition);
39
+
40
+ if (textOnlyAdmonitionMatch) {
41
+ const type = textOnlyAdmonitionMatch[1];
42
+ const title = textOnlyAdmonitionMatch[2]
43
+ ? textOnlyAdmonitionMatch[2]?.trim()
44
+ : undefined;
45
+ const content = textOnlyAdmonitionMatch[3];
46
+
47
+ const admonitionNode = {
48
+ type: "admonition",
49
+ data: {
50
+ hName: "Admonition", // Tells ReactMarkdown to replace the node with Admonition component
51
+ hProperties: {
52
+ type, // Passed as a prop to the Admonition component
53
+ title,
54
+ },
55
+ },
56
+ children: [
57
+ {
58
+ type: "text",
59
+ value: content?.trim(), // Trim leading/trailing whitespace
60
+ },
61
+ ],
62
+ };
63
+ nodes.push(admonitionNode);
64
+ return;
65
+ }
66
+
67
+ if (openingMatch) {
68
+ type = openingMatch[1];
69
+ title = openingMatch[2] || type;
70
+ insideAdmonition = true;
71
+ return;
72
+ }
73
+
74
+ if (closingMatch && insideAdmonition) {
75
+ nodes.push({
76
+ type: "admonition",
77
+ data: {
78
+ hName: "Admonition",
79
+ hProperties: { type: type, title: title },
80
+ },
81
+ children: bufferedChildren,
82
+ });
83
+ bufferedChildren = [];
84
+ insideAdmonition = false;
85
+ type = null;
86
+ title = null;
87
+ return;
88
+ }
89
+ }
90
+
91
+ if (insideAdmonition) {
92
+ bufferedChildren.push(node);
93
+ } else {
94
+ nodes.push(node);
95
+ }
96
+ });
97
+
98
+ if (bufferedChildren.length > 0 && type) {
99
+ nodes.push({
100
+ type: "admonition",
101
+ data: {
102
+ hName: "Admonition",
103
+ hProperties: { type: type, title: title },
104
+ },
105
+ children: bufferedChildren,
106
+ });
107
+ }
108
+ tree.children = nodes;
109
+ };
110
+ }
111
+
112
+ function convertAstToHtmlStr(ast) {
113
+ if (!ast || !Array.isArray(ast)) {
114
+ return "";
115
+ }
116
+
117
+ const convertNode = (node) => {
118
+ switch (node.type) {
119
+ case "text":
120
+ return node.value;
121
+ case "element":
122
+ const { tagName, properties, children } = node;
123
+
124
+ // Convert attributes to a string
125
+ const attrs = properties
126
+ ? Object.entries(properties)
127
+ .map(([key, value]) => `${key}="${value}"`)
128
+ .join(" ")
129
+ : "";
130
+
131
+ // Convert children to HTML
132
+ const childrenHtml = children ? children.map(convertNode).join("") : "";
133
+
134
+ return `<${tagName} ${attrs}>${childrenHtml}</${tagName}>`;
135
+ default:
136
+ return "";
137
+ }
138
+ };
139
+
140
+ return ast.map(convertNode).join("");
141
+ }
13
142
 
14
143
  function Markdown({ children }) {
15
144
  return (
16
- <div>
17
- <ReactMarkdown
18
- children={children}
19
- rehypePlugins={[rehypeRaw]}
20
- components={{
21
- pre: "div",
22
- code({ node, inline, className, children, ...props }) {
23
- const match = /language-(\w+)/.exec(className || "");
24
- if (inline) return <code>{children}</code>;
25
- return !inline && match ? (
26
- <CodeBlock className={className}>{children}</CodeBlock>
27
- ) : (
28
- <CodeBlock>{children}</CodeBlock>
29
- );
30
- },
31
- }}
32
- />
33
- </div>
145
+ <ReactMarkdown
146
+ rehypePlugins={[rehypeRaw]}
147
+ remarkPlugins={[remarkGfm, remarkAdmonition]}
148
+ components={{
149
+ pre: (props) => <div {...props} />,
150
+ code({ node, inline, className, children, ...props }) {
151
+ const match = /language-(\w+)/.exec(className || "");
152
+ return match ? (
153
+ <CodeBlock className={className} language={match[1]} {...props}>
154
+ {children}
155
+ </CodeBlock>
156
+ ) : (
157
+ <code className={className} {...props}>
158
+ {children}
159
+ </code>
160
+ );
161
+ },
162
+ admonition: ({ node, ...props }) => {
163
+ const type = node.data?.hProperties?.type || "note";
164
+ const title = node.data?.hProperties?.title || type;
165
+ const content = convertAstToHtmlStr(node.children);
166
+ return (
167
+ <Admonition type={type} title={title} {...props}>
168
+ <div dangerouslySetInnerHTML={{ __html: content }} />
169
+ </Admonition>
170
+ );
171
+ },
172
+ }}
173
+ >
174
+ {children}
175
+ </ReactMarkdown>
34
176
  );
35
177
  }
36
178