markdown-it-git-graph
Version:
一个markdown-it插件,用于生成git提交图
167 lines (166 loc) • 4.73 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getBranches = getBranches;
exports.getSortedCommits = getSortedCommits;
exports.parseBranch = parseBranch;
exports.parseCommit = parseCommit;
const branchRegex = /^\[.*\]/;
function parseBranch(id, row) {
if (branchRegex.test(row)) {
return {
id,
name: row.substring(1, row.indexOf(']')),
commits: [],
};
}
}
function parseCommit(row, branch) {
const cells = toCells(row);
if (cells.length < 2) {
return;
}
const commit = {
hash: cells[0],
message: cells[1],
date: 0,
branch,
};
if (cells.length > 2) {
const date = Date.parse(cells[2]);
commit.date = Number.isNaN(date) ? 0 : date;
}
if (commit.hash.includes('<')) {
const strs = commit.hash.split('<');
if (strs.length < 2) {
return;
}
commit.hash = strs[0];
if (strs[1].includes('>')) {
strs[1] = strs[1].split('>')[0]?.trim();
}
commit.merge = strs[1] && strs[1].length > 0 ? strs[1] : undefined;
}
if (commit.hash.trim().length <= 0) {
return;
}
if (commit.branch.commits.length > 0) {
commit.branch.commits[commit.branch.commits.length - 1].base = commit.hash;
}
branch.commits.push(commit);
return commit;
}
function toCells(row) {
const cells = [];
let flag = true;
for (let i = 0, s = 0, len = row.length; i < len; i++) {
if (row[i] === ' ' && flag) {
if (i === s) {
s++;
continue;
}
cells.push(row.slice(s, i));
s = i + 1;
continue;
}
if (row[i] === '\'') {
if (flag && i === s) {
s++;
}
flag = !flag;
if (flag && i !== s) {
cells.push(row.substring(s, i));
s = i + 1;
continue;
}
}
if (i === len - 1) {
if (s <= i) {
cells.push(row.substring(s, i + 1));
}
break;
}
}
return cells.map(v => v.trim()).filter(v => v.length > 0);
}
function getBranches(text, defaultBranchName) {
const rows = text
.replace(/`/g, '')
.replace(/\r\n/g, '\n')
.trim()
.split('\n');
const branches = [];
const commitMap = {};
for (let row of rows) {
row = row.replace(/\\s/g, '').trim();
if (row === '') {
continue;
}
const branch = parseBranch(branches.length, row);
if (branch !== undefined) {
branches.push(branch);
continue;
}
if (branches.length === 0) {
branches.push({
id: 0,
name: defaultBranchName,
commits: [],
});
}
const commit = parseCommit(row, branches[branches.length - 1]);
if (commit === undefined) {
continue;
}
commitMap[commit.hash] = commit;
}
branches.forEach(branch => branch.commits.reverse());
Object.keys(commitMap).forEach((hash) => {
const commit = commitMap[hash];
if (commit.merge && !commitMap[commit.merge]) {
commit.merge = undefined;
}
});
return branches;
}
function getSortedCommits(branchs) {
const commitMap = {};
const commits = [];
const count = branchs.reduce((sum, branch) => sum + branch.commits.length, 0);
const branchLoopIdxs = Array.from({
length: branchs.length,
}, () => 0);
while (commits.length < count) {
let bi = -1;
for (let i = 0; i < branchs.length; i++) {
const branch = branchs[i];
const j = branchLoopIdxs[i];
if (j >= branch.commits.length) {
continue;
}
if (bi < 0) {
bi = i;
continue;
}
const pre = branchs[bi].commits[branchLoopIdxs[bi]];
if (pre.merge && !commitMap[pre.merge]) {
bi = i;
continue;
}
const curr = branch.commits[j];
if (curr.merge && !commitMap[curr.merge]) {
continue;
}
if (curr.date < pre.date) {
bi = i;
}
}
if (bi < 0) {
break;
}
const commit = branchs[bi].commits[branchLoopIdxs[bi]];
commits.push(commit);
commitMap[commit.hash] = commit;
branchLoopIdxs[bi]++;
}
return commits.reverse();
}