diff --git a/package.json b/package.json index 44e395dbe6..fbc4e4a55a 100644 --- a/package.json +++ b/package.json @@ -84,6 +84,7 @@ "devDependencies": { "@types/react": "^15.0.38", "@types/react-dom": "~0.14.18", + "ansi-styles": "^3.2.0", "antd-tools": "~2.1.0", "babel-cli": "^6.18.0", "babel-eslint": "^8.0.1", @@ -99,6 +100,7 @@ "bisheng-plugin-react": "^0.5.0", "bisheng-plugin-toc": "^0.4.0", "color-standalone": "^0.11.6", + "commander": "^2.11.0", "cross-env": "^5.0.3", "css-split-webpack-plugin": "^0.2.3", "dekko": "^0.2.0", @@ -120,6 +122,7 @@ "jest": "^21.1.0", "jsonml.js": "^0.1.0", "lint-staged": "^4.0.2", + "majo": "^0.4.1", "mockdate": "^2.0.1", "moment-timezone": "^0.5.5", "pre-commit": "^1.2.2", @@ -138,11 +141,16 @@ "react-intl": "^2.0.1", "react-sublime-video": "^0.2.0", "react-test-renderer": "^15.5.4", + "remark-frontmatter": "^1.1.0", + "remark-parse": "^4.0.0", + "remark-stringify": "^4.0.0", + "remark-yaml-config": "^4.0.1", "reqwest": "^2.0.5", "rimraf": "^2.5.4", "stylelint": "^8.0.0", "stylelint-config-standard": "^17.0.0", "typescript": "~2.5.3", + "unified": "^6.1.5", "values.js": "^1.0.3", "xhr2": "^0.1.3" }, diff --git a/scripts/sort-api-table.js b/scripts/sort-api-table.js new file mode 100644 index 0000000000..d7b92a9ca9 --- /dev/null +++ b/scripts/sort-api-table.js @@ -0,0 +1,108 @@ +const program = require('commander'); +const majo = require('majo'); +const style = require('ansi-styles'); + +const unified = require('unified'); +const parse = require('remark-parse'); +const stringify = require('remark-stringify'); + +const yamlConfig = require('remark-yaml-config'); +const frontmatter = require('remark-frontmatter'); + +const remarkWithYaml = unified() + .use(parse) + .use(stringify, { + paddedTable: false, + listItemIndent: 1, + }) + .use(frontmatter) + .use(yamlConfig); + +const stream = majo(); + +function getCellValue(node) { + return node.children[0].children[0].value; +} + +function innerSort(nodes) { + return nodes.sort((prev, next) => { + // use toLowerCase to keep `case insensitive` + prev = getCellValue(prev).toLowerCase(); + next = getCellValue(next).toLowerCase(); + + // follow the alphabet order + if (prev > next) { + return 1; + } + + if (prev < next) { + return -1; + } + + return 0; + }); +} + +function sort(ast) { + ast.children.forEach((child) => { + const staticProp = []; + // prefix with `on` + const dynamicProp = []; + + // find table markdown type + if (child.type === 'table') { + // slice will create new array, so sort can affect the original array. + // slice(1) cut down the thead + child.children.slice(1).forEach((node) => { + const value = getCellValue(node); + if (/^on[A-Z]/.test(value)) { + dynamicProp.push(node); + } else { + staticProp.push(node); + } + }); + + child.children = [ + child.children[0], + ...innerSort(staticProp), + ...innerSort(dynamicProp), + ]; + } + }); + + return ast; +} + +function sortAPI(md) { + return remarkWithYaml.stringify(sort(remarkWithYaml.parse(md))); +} + +program + .version('0.1.0') + .option( + '-f, --file [file]', + 'Specify which file to be transformed', + // default value + 'components/**/index.+(zh-CN|en-US).md' + ) + .parse(process.argv); + +function sortMiddleware(ctx) { + Object.keys(ctx.files).forEach((filename) => { + const content = ctx.fileContents(filename); + ctx.writeContents(filename, sortAPI(content)); + }); +} + +// Get the markdown file all need to be transformed +stream + .source(program.file) + .use(sortMiddleware) + .dest('.') + .then(() => { + /* eslint-disable no-console */ + console.log( + `${style.green.open}sort ant-design api successfully!${style.green.close}` + ); + /* eslint-enable no-console */ + });