You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by ur...@apache.org on 2022/02/11 05:49:03 UTC

[pulsar-site] 02/02: migrate script: find-docs.js

This is an automated email from the ASF dual-hosted git repository.

urfree pushed a commit to branch refactor/migrate-scripts
in repository https://gitbox.apache.org/repos/asf/pulsar-site.git

commit e024f06957d640937f328450da5b8c2581424da6
Author: LiLi <ur...@apache.org>
AuthorDate: Fri Feb 11 13:48:29 2022 +0800

    migrate script: find-docs.js
    
    Signed-off-by: LiLi <ur...@apache.org>
---
 site2/website-next/migrate/.gitignore              |   3 +
 site2/website-next/migrate/README.md               |   3 +
 site2/website-next/migrate/migrate-change.js       |   0
 site2/website-next/migrate/migrate-chapter.js      |   0
 site2/website-next/migrate/migrate-docs.js         |  50 ++++++++++
 site2/website-next/migrate/migrate-full.js         |   0
 site2/website-next/migrate/migrate-version.js      |   0
 site2/website-next/migrate/tool/find-docs.js       | 106 +++++++++++++++++++++
 site2/website-next/migrate/tool/fix-code.js        |  41 ++++++++
 site2/website-next/migrate/tool/fix-jsx.js         |   7 ++
 site2/website-next/migrate/tool/fix-md.js          |  54 +++++++++++
 site2/website-next/migrate/tool/fix-miss.js        |  59 ++++++++++++
 site2/website-next/migrate/tool/fix-space.js       |  54 +++++++++++
 site2/website-next/migrate/tool/fix-tab.js         |  97 +++++++++++++++++++
 site2/website-next/migrate/tool/fix-table.js       |  72 ++++++++++++++
 .../migrate/tool/fix-tip-note-in-list.js           |  27 ++++++
 site2/website-next/migrate/tool/fix-tip-note.js    |  81 ++++++++++++++++
 17 files changed, 654 insertions(+)

diff --git a/site2/website-next/migrate/.gitignore b/site2/website-next/migrate/.gitignore
new file mode 100644
index 0000000..074d008
--- /dev/null
+++ b/site2/website-next/migrate/.gitignore
@@ -0,0 +1,3 @@
+.cache
+/node_modules
+/log
\ No newline at end of file
diff --git a/site2/website-next/migrate/README.md b/site2/website-next/migrate/README.md
new file mode 100644
index 0000000..1199cb3
--- /dev/null
+++ b/site2/website-next/migrate/README.md
@@ -0,0 +1,3 @@
+1. fix docs md
+2. fix missing docs
+3. fix duplicate docs
\ No newline at end of file
diff --git a/site2/website-next/migrate/migrate-change.js b/site2/website-next/migrate/migrate-change.js
new file mode 100644
index 0000000..e69de29
diff --git a/site2/website-next/migrate/migrate-chapter.js b/site2/website-next/migrate/migrate-chapter.js
new file mode 100644
index 0000000..e69de29
diff --git a/site2/website-next/migrate/migrate-docs.js b/site2/website-next/migrate/migrate-docs.js
new file mode 100644
index 0000000..0690a40
--- /dev/null
+++ b/site2/website-next/migrate/migrate-docs.js
@@ -0,0 +1,50 @@
+const fs = require("fs");
+const path = require("path");
+const _ = require("lodash");
+const fixMd = require("./tool/fix-md");
+import { fileURLToPath } from "url";
+
+function travel(dir, callback) {
+  fs.readdirSync(dir).forEach((file) => {
+    callback(path.join(dir, file));
+  });
+}
+
+function fix(version, docsId) {
+  let version_full = "version-" + version;
+  let src = "../../website/versioned_docs/" + version_full;
+  let dest = "../../website-next/versioned_docs/" + version_full;
+  if (version == "next") {
+    src = "../../docs";
+    dest = "../../website-next/docs";
+  }
+  src = path.join(__dirname, src);
+
+  //find docs with id docsId
+   
+  let reg = new RegExp("^id:\\s*version-" + version + "-(incubating-)?");
+
+  //   dest = path.join(__dirname, dest);
+
+  //   travel(src, function (pathname) {
+  //     let filename = path.basename(pathname);
+  //     try {
+  //       fs.statSync(dest);
+  //     } catch {
+  //       fs.mkdirSync(dest);
+  //     }
+  //     console.log(filename);
+  //     let data = fs.readFileSync(pathname, "utf8");
+  //     data = fixMd(data, version);
+  //     // filename = filename == "deploy-dcos.md" ? "deploy-docs.md" : filename;
+  //     fs.writeFileSync(path.join(dest, filename), data);
+  //   });
+}
+
+module.exports = fix;
+
+// if (process.argv[1] === fileURLToPath(import.meta.url)) {
+//   const args = process.argv.slice(2);
+//   const version = args[0];
+//   const docsId = args[1];
+// }
diff --git a/site2/website-next/migrate/migrate-full.js b/site2/website-next/migrate/migrate-full.js
new file mode 100644
index 0000000..e69de29
diff --git a/site2/website-next/migrate/migrate-version.js b/site2/website-next/migrate/migrate-version.js
new file mode 100644
index 0000000..e69de29
diff --git a/site2/website-next/migrate/tool/find-docs.js b/site2/website-next/migrate/tool/find-docs.js
new file mode 100644
index 0000000..8012b26
--- /dev/null
+++ b/site2/website-next/migrate/tool/find-docs.js
@@ -0,0 +1,106 @@
+const fs = require("fs");
+const path = require("path");
+
+function _log(msg) {
+  if (typeof require !== "undefined" && require.main === module) {
+    console.log(msg);
+  }
+}
+
+const _search = (dir, version, docsId, reg) => {
+  let pathname = path.join(dir, docsId + ".md");
+  if (fs.existsSync(pathname)) {
+    let data = fs.readFileSync(pathname, "utf8");
+    if (reg.test(data)) {
+      _log("[" + version + ":" + docsId + "]fund: " + pathname);
+      return pathname;
+    }
+  }
+  let docsList = fs.readdirSync(dir);
+  for (let filename of docsList) {
+    let pathname = path.join(dir, filename);
+    if (fs.statSync(pathname).isDirectory()) {
+      continue;
+    }
+    if (!pathname.endsWith(".md")) {
+      continue;
+    }
+    let data = fs.readFileSync(pathname, "utf8");
+    if (reg.test(data)) {
+      _log("[" + version + ":" + docsId + "]fund: " + pathname);
+      return pathname;
+    }
+  }
+  return null;
+};
+
+const find = (version, docsId) => {
+  let vReg = new RegExp("id:\\s*version-(\\d\\.?)+-(incubating-)?" + docsId);
+  let nextReg = new RegExp("id:\\s*" + docsId);
+
+  let version_full = "version-" + version;
+  let src = "../../../website/versioned_docs/" + version_full;
+  if (version == "next") {
+    src = "../../../docs";
+  }
+  src = path.join(__dirname, src);
+  nextDir = path.join(__dirname, "../../../docs");
+  vDocsDir = path.join(__dirname, "../../../website/versioned_docs");
+
+  let pathname = _search(
+    src,
+    version,
+    docsId,
+    version == "next" ? nextReg : vReg
+  );
+  if (pathname || version == "next") {
+    return pathname;
+  }
+
+  if (!pathname) {
+    _log("[" + version + ":" + docsId + "]not fund, will auto fix missing");
+    pathname = _search(nextDir, version, docsId, nextReg);
+    if (!pathname) {
+      let vDocsDirList = fs.readdirSync(vDocsDir);
+      vDocsDirList = vDocsDirList.sort((a, b) => {
+        let aVersion = /((\d\.?)+)/.exec(a)[1];
+        let bVersion = /((\d\.?)+)/.exec(b)[1];
+        aVersion = parseInt(aVersion.replace(/\./g, ""));
+        bVersion = parseInt(bVersion.replace(/\./g, ""));
+        return bVersion - aVersion;
+      });
+      for (let vDir of vDocsDirList) {
+        pathname = _search(path.join(vDocsDir, vDir), version, docsId, vReg);
+        if (pathname) {
+          break;
+        }
+      }
+    }
+  }
+
+  let log = "{}";
+  let logdir = path.join(__dirname, "../log");
+  let logpath = path.join(__dirname, "../log", version + ".missing");
+  if (!fs.existsSync(logdir)) {
+    fs.mkdirSync(logdir);
+  }
+  if (fs.existsSync(logpath)) {
+    log = fs.readFileSync(logpath, "utf8");
+  }
+  log = JSON.parse(log);
+  log[docsId] = pathname ? pathname : "";
+  fs.writeFileSync(path.join(logpath), JSON.stringify(log));
+
+  if (!pathname) {
+    _log("[" + version + ":" + docsId + "]not fund and fix missing fail");
+  }
+
+  return pathname;
+};
+
+module.exports = find;
+
+//Test
+if (typeof require !== "undefined" && require.main === module) {
+  find("2.6.0", "adaptors-kafka");
+}
diff --git a/site2/website-next/migrate/tool/fix-code.js b/site2/website-next/migrate/tool/fix-code.js
new file mode 100644
index 0000000..b297473
--- /dev/null
+++ b/site2/website-next/migrate/tool/fix-code.js
@@ -0,0 +1,41 @@
+module.exports = (data) => {
+  let nData = data;
+
+  let reg = /^([\t ]*)(>*)([\t ]*)(```.*)((((?!```).)*\n*)+)```/gm; //代码块
+  while ((codeGroup = reg.exec(data))) {
+    let _match = codeGroup[0];
+    let space1 = codeGroup[1];
+    let arrow = codeGroup[2];
+    let space2 = codeGroup[3];
+    let begin = codeGroup[4];
+    let code = codeGroup[5];
+    let prefix = space1 + arrow + space2;
+    if ((code = /[\t ]*(.+\n*)*\S/.exec(code))) {
+      code = code[0]; //剔除纯空白的行首和行尾, 得到纯代码
+      if (code.substr(0, prefix.length) != prefix) {
+        code = prefix + code.replace(/\n(.*)/g, "\n" + prefix + "$1"); //行对齐
+      }
+    }
+    let newCodeBlock =
+      "\n" +
+      prefix +
+      begin +
+      "\n" +
+      prefix +
+      "\n" +
+      code +
+      "\n" +
+      prefix +
+      "\n" +
+      prefix +
+      "```" +
+      "\n";
+    nData = nData.replace(_match, newCodeBlock);
+  }
+  return nData
+    .replace(
+      /(.*)(\s*\n){3,}(\s*```.*)((((?!```).)*\n*)+)```.*(\s*\n)+/g,
+      "$1\n\n$3$4```\n\n"
+    ) //解决多个空行
+    .replace(/^(\s*```.*(((?!```).)*\n*)+)```.*\n+/gm, "$1```\n\n"); //解决多个空行 //解决代码块结束标识符后无空行
+};
diff --git a/site2/website-next/migrate/tool/fix-jsx.js b/site2/website-next/migrate/tool/fix-jsx.js
new file mode 100644
index 0000000..48bce1c
--- /dev/null
+++ b/site2/website-next/migrate/tool/fix-jsx.js
@@ -0,0 +1,7 @@
+module.exports = (data) => {
+  return data
+    .replace(/(import Tabs from '@theme\/Tabs';)/g, "````mdx-code-block\n$1")
+    .replace(/(import TabItem from '@theme\/TabItem';)/g, "$1\n````")
+    .replace(/(<Tabs>?)/g, "````mdx-code-block\n$1")
+    .replace(/(<\/Tabs>)/g, "$1\n````");
+};
diff --git a/site2/website-next/migrate/tool/fix-md.js b/site2/website-next/migrate/tool/fix-md.js
new file mode 100644
index 0000000..14f15bc
--- /dev/null
+++ b/site2/website-next/migrate/tool/fix-md.js
@@ -0,0 +1,54 @@
+const fixTab = require("./fix-tab");
+const fixTipNote = require("./fix-tip-note");
+const fixTable = require("./fix-table");
+const fixCode = require("./fix-code");
+const fixTipNoteInList = require("./fix-tip-note-in-list");
+const fixJSX = require("./fix-jsx");
+
+function fix(data, version) {
+  let reg = new RegExp("id:\\s*version-" + version + "-(incubating-)?");
+  data = fixTable(data);
+  data = fixTab(data);
+  data = data.replace(/(<TabItem.*)\n(.*{@inject:\s*.+?})/g, "$1\n\n$2");
+  data = data.replace(/^(>\s*```\w*)(\s*\n){2,}>/gm, "$1\n>\n>");
+  data = fixTipNote(data);
+  data = fixTipNoteInList(data);
+  data = fixCode(data);
+
+  data = data
+    .replace(reg, "id: ")
+    .replace("id: deploy-docs", "id: deploy-dcos")
+    .replace(/`{4,}/g, "```")
+    .replace(/^(id:\sstandalone)\s*$/gm, "slug: /\n$1")
+    .replace(/<style[\s\S]*?<\/style>/g, "")
+    .replace(/\[(.*)\]\s*\((.*)\.md\)/g, "[$1]($2)")
+    .replace(/\*\*(((?!\*).)+)\*/g, "**$1**") //**macOS* => **macOS**
+    .replace(/\*\*(((?!\*).)+)\*{3}/g, "**$1**") //**macOS*** => **macOS**
+    .replace(/(\w)[\t ]*\n\[/g, "$1 [")
+    .replace(/sidebar_label:\s*(.*)/, 'sidebar_label: "$1"')
+    .replace(/""(.*)""/, '"$1"')
+    .replace(/\[\[pulsar:version_number\]\]/g, "@pulsar:version_number@")
+    .replace(/{{(pulsar:.*?)}}/g, "@$1@")
+    .replace(/(@inject:\s*\w+:)`(\w+)`/g, "$1$2")
+    .replace(/<empty string>/g, "|")
+    .replace(/<li>(((?!<\/?li>|\|).)+)/g, "<li>$1</li>")
+    .replace(/<\/li>\s*<\/li>/g, "</li>")
+    .replace(/\|(((?!<\/?li>|\|).)+)<\/li>/g, "|<li>$1</li>")
+    .replace(/<\/li>\s*<\/li>/g, "</li>") //sometimes needed, no idea for now...
+    .replace(/<\/br>/g, "@AAA@")
+    .replace(/<br>/g, "@AAA@")
+    .replace(/<br\/>/g, "@AAA@")
+    .replace(/<>/g, "")
+    .replace(/@AAA@/g, "<br />")
+    .replace(
+      /<span style="(((?!:).)+):(((?!>).)+);"/g,
+      '<span style={{color: "$3"}}'
+    )
+    .replace(/\s?style=".*?"/g, "")
+    .replace(/\]\(assets\//g, "](/assets/");
+
+  return data;
+  // return fixJSX(data);
+}
+
+module.exports = fix;
diff --git a/site2/website-next/migrate/tool/fix-miss.js b/site2/website-next/migrate/tool/fix-miss.js
new file mode 100644
index 0000000..f20574b
--- /dev/null
+++ b/site2/website-next/migrate/tool/fix-miss.js
@@ -0,0 +1,59 @@
+const fs = require("fs");
+const path = require("path");
+
+function fix(docId, versions) {
+  console.log("Fix missing for: ", docId, versions);
+
+  let fixed = false;
+
+  function travel(dir, callback) {
+    fs.readdirSync(dir)
+      .sort(() => -1)
+      .forEach((file) => {
+        var pathname = path.join(dir, file);
+        if (fs.statSync(pathname).isDirectory()) {
+          if (!fixed) {
+            travel(pathname, callback);
+          }
+        } else {
+          if (!fixed) {
+            fixed = callback(pathname);
+          }
+        }
+      });
+  }
+
+  const vdocs = path.join(__dirname, "../../website/versioned_docs");
+  travel(vdocs, (pathname) => {
+    let data = fs.readFileSync(pathname, "utf8");
+    let _match = /^id:\s*version-[\d\.]+-(incubating-)?(.*)/gm.exec(data);
+    //   if (_match[1].indexOf(docId) > -1) {
+    if (_match && _match[2] == docId) {
+      console.log(pathname, _match[0]);
+
+      let vs = versions.split(",");
+      vs.forEach((v) => {
+        if (v == "next") {
+          fs.writeFileSync(
+            path.join(vdocs, "../../docs/", docId + ".md"),
+            data.replace(/^id:\s*version-[\d\.]+-(.*)/gm, "id: " + docId),
+            "utf8"
+          );
+        } else {
+          fs.writeFileSync(
+            path.join(vdocs, "version-" + v, docId + ".md"),
+            data.replace(
+              /^id:\s*version-[\d\.]+-(.*)/gm,
+              "id: version-" + v + "-" + docId
+            ),
+            "utf8"
+          );
+        }
+      });
+      return true;
+    }
+    return false;
+  });
+}
+
+module.exports = fix;
diff --git a/site2/website-next/migrate/tool/fix-space.js b/site2/website-next/migrate/tool/fix-space.js
new file mode 100644
index 0000000..56dfd99
--- /dev/null
+++ b/site2/website-next/migrate/tool/fix-space.js
@@ -0,0 +1,54 @@
+const fs = require("fs");
+const path = require("path");
+
+const code_map = {};
+let index = 0;
+
+function fixSpace(data) {
+  const code_reg = /(```\w*)((((?!```).)*\n*)+)```/;
+  const _match = code_reg.exec(data);
+  if (_match) {
+    const code = _match[0];
+    const TMP_KEY = "_TMP_CODE_KEY_" + index + "_";
+    code_map[TMP_KEY] = code;
+    index++;
+    data = data.replace(code_reg, TMP_KEY);
+    return fixSpace(data);
+  } else {
+    return data;
+  }
+}
+
+function fixTmp(data) {
+  const tmp_reg = /_TMP_CODE_KEY_(\d+)_/;
+  const _match = tmp_reg.exec(data);
+  if (_match) {
+    data = data.replace(tmp_reg, code_map[_match[0]]);
+    return fixTmp(data);
+  } else {
+    return data;
+  }
+}
+
+function fix(data) {
+  data = fixSpace(data);
+  data = data.replace(/^[\t ]+/gm, "");
+  data = fixTmp(data);
+  return data;
+}
+
+function test() {
+  let data = fs.readFileSync(
+    path.join(__dirname, "../bak/io-quickstart.md"),
+    "utf8"
+  );
+  data = fixSpace(data);
+  data = data.replace(/^[\t ]+/gm, "");
+  data = fixTmp(data);
+  // console.log(data);
+  fs.writeFileSync(path.join(__dirname, "../bak/io-quickstart-fixed.md"), data);
+}
+
+// test();
+
+module.exports = fix;
diff --git a/site2/website-next/migrate/tool/fix-tab.js b/site2/website-next/migrate/tool/fix-tab.js
new file mode 100644
index 0000000..3dd751a
--- /dev/null
+++ b/site2/website-next/migrate/tool/fix-tab.js
@@ -0,0 +1,97 @@
+const fs = require("fs");
+const path = require("path");
+const lodash = require("lodash");
+const TAB_REG =
+  /([\t ]*)<!--DOCUSAURUS_CODE_TABS-->(((?!<!--END_DOCUSAURUS_CODE_TABS-->).)*\n*)*<!--END_DOCUSAURUS_CODE_TABS-->/;
+
+function removeTabTag(tab) {
+  return tab
+    .replace(/<!--DOCUSAURUS_CODE_TABS-->/, "")
+    .replace(/<!--END_DOCUSAURUS_CODE_TABS-->/, "");
+}
+
+function findTabItemNameList(tab) {
+  const _match = tab.match(/<!--(.*)-->/g);
+  return _match.map((item) => {
+    return item.replace("<!--", "").replace("-->", "");
+  });
+}
+
+function replaceTabItemTag(tab) {
+  const tab_item_reg = /([\t ]*)<!--(.*)-->((((?![\t ]*<!--).)*\n*)*)/;
+  const _match = tab_item_reg.exec(tab);
+  if (_match) {
+    const space = _match[1];
+    const tab_item_name = _match[2];
+    const tab_item_content = lodash.trimEnd(_match[3]);
+    let tab_item_str = space + '<TabItem value="';
+    tab_item_str +=
+      tab_item_name + '">' + tab_item_content + "\n\n" + space + "</TabItem>\n";
+    tab = tab.replace(tab_item_reg, tab_item_str);
+    return replaceTabItemTag(tab);
+  } else {
+    return tab;
+  }
+}
+
+function importTabComponent(data) {
+  if (!/import Tabs from '@theme\/Tabs';/g.exec(data)) {
+    return data.replace(
+      /---((((?!---).)*\n*)*)---/,
+      "---$1---" +
+        "\n\nimport Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';\n"
+    );
+  }
+  return data;
+}
+
+function fixTab(data) {
+  const _match = TAB_REG.exec(data);
+  if (_match) {
+    data = importTabComponent(data);
+    let tab = _match[0];
+    tab = removeTabTag(tab);
+    const names = findTabItemNameList(tab);
+    tab = replaceTabItemTag(tab);
+    const names_map = names.map((item) => {
+      return {
+        label: item,
+        value: item,
+      };
+    });
+
+    const space = _match[1];
+    const tab_tag_begin =
+      space +
+      "<Tabs \n" +
+      space +
+      '  defaultValue="' +
+      names[0] +
+      '"\n' +
+      space +
+      "  values={" +
+      JSON.stringify(names_map) +
+      "}>";
+
+    const tab_tag_end = "\n" + space + "</Tabs>";
+    tab = tab_tag_begin + tab + tab_tag_end;
+    return fixTab(data.replace(TAB_REG, tab));
+  } else {
+    return data
+      .replace(/(<TabItem.*)\n[\t ]*\n/g, "$1\n")
+      .replace(/(<TabItem.*)/g, "$1\n");
+  }
+}
+
+function test() {
+  let data = fs.readFileSync(
+    path.join(__dirname, "../bak/schema-manage.md"),
+    "utf8"
+  );
+  data = fixTab(data);
+  console.log(data);
+}
+
+// test()
+
+module.exports = fixTab;
diff --git a/site2/website-next/migrate/tool/fix-table.js b/site2/website-next/migrate/tool/fix-table.js
new file mode 100644
index 0000000..ef629f8
--- /dev/null
+++ b/site2/website-next/migrate/tool/fix-table.js
@@ -0,0 +1,72 @@
+const fs = require("fs");
+const path = require("path");
+const NL = "\n";
+
+//Convert HTML table to markdown table
+function convertTableElementToMarkdown(table) {
+  let rows = [];
+  let trEls = table.match(/[<]tr[\s\S]*?[/]tr[>]/g);
+  for (let i = 0; i < trEls.length; i++) {
+    let tableRow = trEls[i];
+    let markdownRow = convertTableRowElementToMarkdown(tableRow, i);
+    rows.push(markdownRow);
+  }
+  return rows.join(NL);
+}
+
+//Convert the rows of the HTML table to the rows of the markdown table
+function convertTableRowElementToMarkdown(tableRow, rowNumber) {
+  let cells = [];
+  let cellEls = [];
+  cellEls = tableRow.match(/[<]th[\s\S]*?[/]th[>]/g);
+  if (!cellEls || cellEls.length == 0) {
+    cellEls = tableRow.match(/[<]td[\s\S]*?[/]td[>]/g);
+  }
+  let dividerCells = [];
+  if (rowNumber == 0) {
+    for (i = 0; i < cellEls.length; i++) {
+      dividerCells.push("---" + " |");
+    }
+    dividerCells = "| " + dividerCells.join(" ");
+  }
+  for (let i = 0; i < cellEls.length; i++) {
+    let cell = cellEls[i];
+    cell.indexOf(">") + 1;
+
+    cells.push(
+      cell
+        .substring(cell.indexOf(">") + 1, cell.indexOf("<", cell.indexOf(">")))
+        .replace(/\*\s+([^\|\*]*)/g, "<li>$1</li>") + " | "
+    );
+  }
+  let row = "| " + cells.join(" ");
+  if (rowNumber == 0) {
+    row = row + NL + dividerCells;
+  }
+
+  return row;
+}
+
+function fix(data) {
+  let content = data;
+  let patt1 = /[<]table[\s\S]*?[/]table[>]/g;
+  let tables = content.match(patt1);
+  if (tables) {
+    for (let e of tables) {
+      let et = e.replace(/\s+/g, " ");
+      let markdownTable = convertTableElementToMarkdown(et);
+      content = content.replace(e, markdownTable);
+    }
+  }
+  return content;
+}
+
+function test() {
+  let data = fs.readFileSync(path.join(__dirname, "../bak/txn-how.md"), "utf8");
+  data = fix(data);
+  fs.writeFileSync(path.join(__dirname, "../bak/txn-how-fixed.md"), data);
+}
+
+// test();
+
+module.exports = fix;
diff --git a/site2/website-next/migrate/tool/fix-tip-note-in-list.js b/site2/website-next/migrate/tool/fix-tip-note-in-list.js
new file mode 100644
index 0000000..81a3cba
--- /dev/null
+++ b/site2/website-next/migrate/tool/fix-tip-note-in-list.js
@@ -0,0 +1,27 @@
+module.exports = (data) => {
+  let nData = data;
+  let block = null;
+
+  let uListReg = /^([\*-][\t ]+.*)\n+((\n*[\t ]+.*)*)*/gm;
+
+  while ((block = uListReg.exec(data))) {
+    let content = block[2];
+    if (!content) {
+      continue;
+    }
+    let nContent = content.replace(/^    (?= *)/gm, "  ");
+    nData = nData.replace(content, nContent);
+  }
+
+  let listReg = /^(\d+\.[\t ]+.*)\n+((\n*[\t ]+.*)*)*/gm;
+  while ((block = listReg.exec(data))) {
+    let content = block[2];
+    if (!content) {
+      continue;
+    }
+    let nContent = content.replace(/^    (?= *)/gm, "   ");
+    nData = nData.replace(content, nContent);
+  }
+
+  return nData;
+};
diff --git a/site2/website-next/migrate/tool/fix-tip-note.js b/site2/website-next/migrate/tool/fix-tip-note.js
new file mode 100644
index 0000000..6becf1a
--- /dev/null
+++ b/site2/website-next/migrate/tool/fix-tip-note.js
@@ -0,0 +1,81 @@
+const fs = require("fs");
+const path = require("path");
+
+function fixTip(data) {
+  const _reg =
+    /^([\t ]*)>[\t ]*#*[\t ]*\**(Note|Tip)+s?:?\**[\t ]*\n(([\t ]*)>[\t ]*[^><].*\n)+/gm;
+  const _type_reg = /#*[\t ]*\**(Note|Tip)+s?:?\**[\t ]*/i;
+
+  let type = "note";
+  let _tips = data.match(_reg);
+  if (!_tips) {
+    return data;
+  }
+  for (let _tip of _tips) {
+    let tip = _tip.replace(/^[ ]>/gm, ">").replace(/^([\t ]*>)[\t ]*/gm, "$1");
+    let type_match = _type_reg.exec(tip);
+    if (type_match) {
+      type = type_match[1] + "";
+      type = type.toLowerCase();
+    }
+    let space = /^([\t ]*)>/.exec(tip)[1];
+    // if (space.length % 2 == 1) {
+    //   space = space.substr(1);
+    // }
+    tip = tip
+      .replace(_type_reg, "")
+      .replace(/^([\t ]*)>[\t ]*/gm, space)
+      .replace(/^\s*\n/gm, "");
+    tip = space + ":::" + type + "\n\n" + tip + "\n" + space + ":::\n";
+    data = data.replace(_tip, tip);
+  }
+  return data
+    .replace(
+      /(.*)(\s*\n){3,}(\s*:::.*)((((?!:::).)*\n*)+):::.*(\s*\n)+/g,
+      "$1\n\n$3$4:::\n\n"
+    ) //解决多个空行
+    .replace(/(\s*:::.*(((?!:::).)*\n*)+):::.*\n+/g, "$1:::\n\n"); //解决多个空行 //解决代码块结束标识符后无空行
+}
+
+// function fixListWithTip(data) {
+//   const _reg = /^([*-]\s+.*)([\s\S]*?)(:::[\s\S]*?:::)/gm;
+//   let _match = data.match(_reg);
+//   if (!_match) {
+//     return data;
+//   }
+//   for (let _m of _match) {
+//     let __m = _m.match(/^([*-]\s+.*)([\s\S]*?)(:::[\s\S]*?:::)/m);
+//     let top = __m[1];
+//     let seconds = __m[2];
+//     let tip = __m[3];
+//     // seconds = seconds.replace(/^([\t ]*)(\w+)/gm, "$1* $2");
+//     tip = tip.replace(/^[\t ]+/gm, "");
+//     data = data
+//       .replace(_m, top + seconds + "\n" + tip)
+//       .replace(/(\s*\n){3,}:::/g, "\n\n:::")
+//       .replace(/:::(\s*\n){3,}/g, ":::\n\n");
+//   }
+//   return data;
+// }
+
+function fix(data) {
+  data = fixTip(data);
+  // data = fixListWithTip(data);
+  return data;
+}
+
+function test() {
+  let data = fs.readFileSync(
+    path.join(__dirname, "../bak/tiered-storage-overview.md"),
+    "utf8"
+  );
+  data = fix(data);
+  fs.writeFileSync(
+    path.join(__dirname, "../bak/tiered-storage-overview-fixed.md"),
+    data
+  );
+}
+
+// test();
+
+module.exports = fix;