Skip to content

Commit 06ef51c

Browse files
committed
feat: experimental temporary support for tags in md
1 parent aaaa899 commit 06ef51c

File tree

1 file changed

+63
-10
lines changed

1 file changed

+63
-10
lines changed

src/services/MarkdownRenderer.ts

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import * as marked from 'marked';
2-
32
import slugify from 'slugify';
4-
import { MDComponent } from '../components/Markdown/Markdown';
3+
54
import { highlight, html2Str } from '../utils';
5+
import { AppStore } from './AppStore';
66
import { SECTION_ATTR } from './MenuStore';
77

88
const renderer = new marked.Renderer();
@@ -14,9 +14,14 @@ marked.setOptions({
1414
},
1515
});
1616

17-
export const COMPONENT_REGEXP = '^\\s*<!-- ReDoc-Inject:\\s+?{component}\\s+?-->\\s*$';
18-
export function buildComponentComment(name: string) {
19-
return `<!-- ReDoc-Inject: <${name}> -->`;
17+
export const LEGACY_REGEXP = '^\\s*<!-- ReDoc-Inject:\\s+?{component}\\s+?-->\\s*$';
18+
export const MDX_COMPONENT_REGEXP = '^\\s*<{component}\\s*?/>\\s*$';
19+
export const COMPONENT_REGEXP = '(?:' + LEGACY_REGEXP + '|' + MDX_COMPONENT_REGEXP + ')';
20+
21+
export interface MDXComponentMeta {
22+
component: React.ComponentType;
23+
propsSelector: (store?: AppStore) => any;
24+
attrs?: object;
2025
}
2126

2227
export interface MarkdownHeading {
@@ -26,6 +31,10 @@ export interface MarkdownHeading {
2631
description?: string;
2732
}
2833

34+
export function buildComponentComment(name: string) {
35+
return `<!-- ReDoc-Inject: <${name}> -->`;
36+
}
37+
2938
export class MarkdownRenderer {
3039
headings: MarkdownHeading[] = [];
3140
currentTopHeading: MarkdownHeading;
@@ -130,20 +139,30 @@ export class MarkdownRenderer {
130139
return res;
131140
}
132141

142+
// TODO: rewrite this completelly! Regexp-based 👎
143+
// Use marked ecosystem
133144
renderMdWithComponents(
134145
rawText: string,
135-
components: Dict<MDComponent>,
146+
components: Dict<MDXComponentMeta>,
136147
raw: boolean = true,
137-
): Array<string | MDComponent> {
148+
): Array<string | MDXComponentMeta> {
138149
const componentDefs: string[] = [];
139-
const anyCompRegexp = new RegExp(COMPONENT_REGEXP.replace('{component}', '(.*?)'), 'gmi');
150+
const names = '(?:' + Object.keys(components).join('|') + ')';
151+
152+
const anyCompRegexp = new RegExp(
153+
COMPONENT_REGEXP.replace(/{component}/g, '(<?' + names + '.*?)'),
154+
'gmi',
155+
);
140156
let match = anyCompRegexp.exec(rawText);
141157
while (match) {
142-
componentDefs.push(match[1]);
158+
componentDefs.push(match[1] || match[2]);
143159
match = anyCompRegexp.exec(rawText);
144160
}
145161

146-
const splitCompRegexp = new RegExp(COMPONENT_REGEXP.replace('{component}', '.*?'), 'mi');
162+
const splitCompRegexp = new RegExp(
163+
COMPONENT_REGEXP.replace(/{component}/g, names + '.*?'),
164+
'mi',
165+
);
147166
const htmlParts = rawText.split(splitCompRegexp);
148167
const res: any[] = [];
149168
for (let i = 0; i < htmlParts.length; i++) {
@@ -171,6 +190,40 @@ function parseComponent(
171190
): {
172191
componentName?: string;
173192
attrs: any;
193+
} {
194+
if (htmlTag.startsWith('<')) {
195+
return legacyParse(htmlTag);
196+
}
197+
198+
const match = /([\w_-]+)(\s+[\w_-]+\s*={[^}]*?})*/.exec(htmlTag);
199+
if (match === null || match.length <= 1) {
200+
return { componentName: undefined, attrs: {} };
201+
}
202+
const componentName = match[1];
203+
const attrs = {};
204+
for (let i = 2; i < match.length; i++) {
205+
if (!match[i]) {
206+
continue;
207+
}
208+
const [name, value] = match[i]
209+
.trim()
210+
.split('=')
211+
.map(p => p.trim());
212+
213+
// tslint:disable-next-line
214+
attrs[name] = value.startsWith('{') ? eval(value.substr(1, value.length - 2)) : eval(value);
215+
}
216+
return {
217+
componentName,
218+
attrs,
219+
};
220+
}
221+
222+
function legacyParse(
223+
htmlTag: string,
224+
): {
225+
componentName?: string;
226+
attrs: any;
174227
} {
175228
const match = /<([\w_-]+).*?>/.exec(htmlTag);
176229
if (match === null || match.length <= 1) {

0 commit comments

Comments
 (0)