Skip to content

Commit

Permalink
refactor: refactor transform code & api.
Browse files Browse the repository at this point in the history
  • Loading branch information
jaywcjlove committed May 11, 2022
1 parent 46bf9cf commit 59eab07
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 150 deletions.
56 changes: 41 additions & 15 deletions core/README-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export default (conf: Configuration, env: 'development' | 'production', options:

```ts
import { PluginItem } from '@babel/core';
import { Options as RIOptions } from 'babel-plugin-transform-remove-imports'
import { Options as RemoveImportsOptions } from 'babel-plugin-transform-remove-imports'
export type Options = {
/**
* 需要解析代码块的语言,默认: `["jsx","tsx"]`
Expand All @@ -95,7 +95,7 @@ export type Options = {
* babel (babel-plugin-transform-remove-imports) 包的 option 设置
* https://github.com/uiwjs/babel-plugin-transform-remove-imports
*/
removeImports?: RIOptions;
removeImports?: RemoveImportsOptions;
/**
* 添加 babel 插件。
*/
Expand All @@ -110,30 +110,54 @@ export type Options = {
```jsx
import mdObj from 'markdown-react-code-preview-loader/README.md';

mdObj.source // => `README.md` 原始字符串文本
mdObj.components // => 组件索引对象,从 markdown 索引到的示例转换成的 React 组件。(需要配置 meta)
mdObj.codeBlock // => 组件源码索引对象,从 markdown 索引到的示例源码。(需要配置 meta)
mdObj.source // => `README.md` 原始字符串文本
mdObj.components // => 组件索引对象,从 markdown 索引到的示例转换成的 React 组件。(可能需要配置 meta)
mdObj.data // => 组件源码索引对象,从 markdown 索引到的示例源码。(可能需要配置 meta)
```

```js
{
codeBlock: {
17: 'import React from ...',
77: 'import React from ...',
demo12: 'import React from ...'
data: {
17: {
code: "\"use strict\";\n\nfunction ......"
language: "jsx"
name: 17,
value: "impo....."
},
77: {
code: "\"use strict\";\n\nfunction ......"
language: "jsx"
name: 17,
value: "impo....."
},
demo12: {
code: "\"use strict\";\n\nfunction ......"
language: "jsx"
name: 17,
value: "impo....."
}
},
components: { 17: ƒ, 77: ƒ, demo12: ƒ },
languages: { 17: 'jsx', 77: 'jsx', demo12: 'jsx'},
source: "# Alert 确认对话框...."
}
```

```ts
export type CodeBlockItem = {
/** 源码转换后的代码。 **/
code?: string;
/** 原始代码块 **/
value?: string;
/** 代码块编程语言 **/
language?: string;
/** 索引名称可以自定义,可以是行号。 */
name?: string | number;
};

export type CodeBlockData = {
source: string;
components: Record<string | number, React.FC>;
codeBlock: Record<string | number, string>;
languages: Record<string | number, string>;
components: Record<CodeBlockItem['name'], React.FC>;
data: Record<CodeBlockItem['name'], CodeBlockItem>;
};
```

Expand All @@ -156,9 +180,11 @@ getMetaId('mdx:preview') // => ''
getMetaId('mdx:preview:demo12') // => 'demo12'
```

## getCodeBlockString
## getCodeBlock

传递 `markdown` 文件内容字符串,返回转换好的需要预览的代码块解析数据。
```ts
const getCodeBlock: (child: MarkdownParseData['children'], opts?: Options) => CodeBlockData['data'];
```

## 配置 meta 标识

Expand Down
56 changes: 41 additions & 15 deletions core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export default (conf: Configuration, env: 'development' | 'production', options:

```ts
import { PluginItem } from '@babel/core';
import { Options as RIOptions } from 'babel-plugin-transform-remove-imports'
import { Options as RemoveImportsOptions } from 'babel-plugin-transform-remove-imports'
export type Options = {
/**
* Language to parse code blocks, default: `["jsx","tsx"]`
Expand All @@ -94,7 +94,7 @@ export type Options = {
* Option settings for the babel (babel-plugin-transform-remove-imports) package
* https://github.com/uiwjs/babel-plugin-transform-remove-imports
*/
removeImports?: RIOptions;
removeImports?: RemoveImportsOptions;
/**
* Add babel plugins.
*/
Expand All @@ -109,30 +109,54 @@ After adding `loader`, use the method to load `markdown` text in the project pro
```jsx
import mdObj from 'markdown-react-code-preview-loader/README.md';

mdObj.source // => `README.md` raw string text
mdObj.components // => The component index object, the React component converted from the markdown indexed example. (need to configure meta)
mdObj.codeBlock // => The component source code index object, the sample source code indexed from markdown. (need to configure meta)
mdObj.source // => `README.md` raw string text
mdObj.components // => The component index object, the React component converted from the markdown indexed example. (need to configure meta)
mdObj.data // => The component source code index object, the sample source code indexed from markdown. (need to configure meta)
```

```js
{
codeBlock: {
17: 'import React from ...',
77: 'import React from ...',
demo12: 'import React from ...'
data: {
17: {
code: "\"use strict\";\n\nfunction ......"
language: "jsx"
name: 17,
value: "impo....."
},
77: {
code: "\"use strict\";\n\nfunction ......"
language: "jsx"
name: 17,
value: "impo....."
},
demo12: {
code: "\"use strict\";\n\nfunction ......"
language: "jsx"
name: 17,
value: "impo....."
}
},
components: { 17: ƒ, 77: ƒ, demo12: ƒ },
languages: { 17: 'jsx', 77: 'jsx', demo12: 'jsx'},
source: "# Alert 确认对话框...."
}
```

```ts
export type CodeBlockItem = {
/** The code after the source code conversion. **/
code?: string;
/** original code block **/
value?: string;
/** code block programming language **/
language?: string;
/** The index name, which can be customized, can be a row number. */
name?: string | number;
};

export type CodeBlockData = {
source: string;
components: Record<string | number, React.FC>;
codeBlock: Record<string | number, string>;
languages: Record<string | number, string>;
components: Record<CodeBlockItem['name'], React.FC>;
data: Record<CodeBlockItem['name'], CodeBlockItem>;
};
```

Expand All @@ -155,9 +179,11 @@ getMetaId('mdx:preview') // => ''
getMetaId('mdx:preview:demo12') // => 'demo12'
```

## getCodeBlockString
## getCodeBlock

Pass the `markdown` file content string, and return the converted code block parsing data that needs to be previewed.
```ts
const getCodeBlock: (child: MarkdownParseData['children'], opts?: Options) => CodeBlockData['data'];
```

## Configure meta ID

Expand Down
41 changes: 27 additions & 14 deletions core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
import React from 'react';
import { PluginItem } from '@babel/core';
import { Options as RIOptions } from 'babel-plugin-transform-remove-imports';
import { getCodeBlockString } from './utils';
import { getProcessor, getCodeBlock } from './utils';
export * from './utils';

export type CodeBlockItem = {
/** The code after the source code conversion. **/
code?: string;
/** original code block **/
value?: string;
/** code block programming language **/
language?: string;
/** The index name, which can be customized, can be a row number. */
name?: string | number;
};

export type CodeBlockData = {
source: string;
components: Record<string | number, React.FC>;
codeBlock: Record<string | number, string>;
languages: Record<string | number, string>;
components: Record<CodeBlockItem['name'], React.FC>;
data: Record<CodeBlockItem['name'], CodeBlockItem>;
};

export const FUNNAME_PREFIX = '__BaseCode__';

export type Options = {
/**
* Language to parse code blocks, default: `["jsx","tsx"]`
Expand All @@ -29,15 +41,16 @@ export type Options = {

export default function (source: string) {
const options: Options = this.getOptions();
const result = getCodeBlockString(source, options);

return `
${result}
export default {
source:${JSON.stringify(source)},
components,
codeBlock,
languages
}
`;
const codeBlock = getCodeBlock(getProcessor(source), options);
let components = '';
Object.keys(codeBlock).forEach((key) => {
components += `${key}: (function() { ${codeBlock[key].code} })(),`;
});

return `\nexport default {
components: { ${components} },
data: ${JSON.stringify(codeBlock, null, 2)},
source: ${JSON.stringify(source)}
}`;
}
63 changes: 19 additions & 44 deletions core/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
/*
* @Description: markdown 转化
*/
import { MarkDownTreeType, CodeBlockItemType } from './interface';
import { Parent, Node } from 'unist';
import { getTransformValue } from './transform';
import webpack from 'webpack';
import remark from 'remark';
export * from './interface';
import { Options } from '../';
import { Options, FUNNAME_PREFIX, CodeBlockItem, CodeBlockData } from '../';

export interface MarkdownDataChild extends Node {
lang: string;
meta: string;
value: string;
}

export interface MarkdownParseData extends Parent<MarkdownDataChild> {}

/** 转换 代码*/
const getProcessor = (scope: string) => {
export const getProcessor = (source: string) => {
try {
const child = remark.parse(scope) as MarkDownTreeType;
const child = remark.parse(source) as MarkdownParseData;
return child.children;
} catch (err) {
console.warn(err);
Expand Down Expand Up @@ -43,22 +47,22 @@ export const getMetaId = (meta: string = '') => {
export const isMeta = (meta: string = '') => meta && meta.includes('mdx:preview');

/** 获取需要渲染的代码块 **/
const getCodeBlock = (child: MarkDownTreeType['children'], opts: Options = {}) => {
export const getCodeBlock = (child: MarkdownParseData['children'], opts: Options = {}): CodeBlockData['data'] => {
const { lang = ['jsx', 'tsx'] } = opts;
// 获取渲染部分
const codeBlock: Record<string | number, CodeBlockItemType> = {};
const codeBlock: Record<string | number, CodeBlockItem> = {};
try {
child.forEach((item) => {
if (item && item.type === 'code' && lang.includes(item.lang)) {
const line = item.position.start.line;
const metaId = getMetaId(item.meta);
if (isMeta(item.meta)) {
let name = typeof metaId === 'string' ? metaId : line;
const funName = `BaseCode${line}`;
const returnCode = getTransformValue(item.value, `${funName}.${lang}`, funName, opts);
codeBlock[line] = {
code: returnCode,
let name = metaId || line;
const funName = `${FUNNAME_PREFIX}${name}`;
const returnCode = getTransformValue(item.value, `${funName}.${lang}`, opts);
codeBlock[name] = {
name,
code: returnCode,
language: item.lang,
value: item.value,
};
Expand All @@ -71,35 +75,6 @@ const getCodeBlock = (child: MarkDownTreeType['children'], opts: Options = {}) =
return codeBlock;
};

const createStr = (codeBlock: Record<string | number, CodeBlockItemType>) => {
let baseCodeStr = ``;
let baseCodeObjStr = ``;
let codeBlockValue = ``;
let languageStr = ``;

try {
Object.entries(codeBlock).forEach(([key, item]) => {
const { code, value, language, name } = item;
baseCodeStr += `${code};\n`;
baseCodeObjStr += `${name}:BaseCode${key},\n`;
codeBlockValue += `${name}:${JSON.stringify(value)},\n`;
languageStr += `${name}:\`${language}\`,\n`;
});
} catch (err) {
console.warn(err);
}

let indexStr = `${baseCodeStr} const languages={${languageStr}};\n const codeBlock={${codeBlockValue}};\n const components={${baseCodeObjStr}}`;
return indexStr;
};

export const getCodeBlockString = (scope: string, opts: Options = {}) => {
const children = getProcessor(scope);
const codeBlock = getCodeBlock(children, opts);
const result = createStr(codeBlock);
return result;
};

/**
* `mdCodeModulesLoader` method for adding `markdown-react-code-preview-loader` to webpack config.
* @param {webpack.Configuration} config webpack config
Expand Down
34 changes: 0 additions & 34 deletions core/src/utils/interface.ts

This file was deleted.

Loading

0 comments on commit 59eab07

Please sign in to comment.