You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by ov...@apache.org on 2020/06/17 11:17:13 UTC
[incubator-echarts-handbook] 09/11: feat: contributors of each file
This is an automated email from the ASF dual-hosted git repository.
ovilia pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-echarts-handbook.git
commit bb7e1c2a676f9f51ee7febf7a9558084e5575116
Author: Ovilia <zw...@gmail.com>
AuthorDate: Tue May 12 16:22:07 2020 +0800
feat: contributors of each file
---
build/generate-contributors.js | 38 ++++++++++++++++++++++++++++++++++++++
configs/config.js | 3 ++-
contents/zh/chart-types/line.md | 2 ++
contents/zh/chart-types/xxx.md | 0
contents/zh/concepts/legend.md | 0
contents/zh/cookbook/downplay.md | 0
contents/zh/cookbook/mobile.md | 0
layouts/default.vue | 39 ++++++++++++++++++++++++++++++++++++++-
package-lock.json | 14 +++++++++++---
package.json | 1 +
pages/helper/contributors.ts | 1 +
pages/helper/post.ts | 9 ++++++---
pages/zh/_post.vue | 17 ++++++++++++++++-
13 files changed, 115 insertions(+), 9 deletions(-)
diff --git a/build/generate-contributors.js b/build/generate-contributors.js
new file mode 100644
index 0000000..20d615b
--- /dev/null
+++ b/build/generate-contributors.js
@@ -0,0 +1,38 @@
+const { exec } = require('child_process');
+const fs = require('fs');
+
+const dir = './contents';
+
+const entries = {};
+const paths = [];
+
+const loopDir = path => {
+ if (fs.lstatSync(path).isDirectory()) {
+ const children = fs.readdirSync(path);
+ children.forEach(child => loopDir([path, child].join('/')));
+ }
+ else {
+ paths.push(path);
+ }
+}
+
+loopDir(dir);
+
+for (let i = 0; i < paths.length; ++i) {
+ const cmd = `git log --pretty=format:"%an%x09" ${paths[i]} | sort | uniq`;
+ (i => {
+ exec(cmd, (err, stdout) => {
+ if (err) {
+ console.error(err);
+ }
+ else {
+ const key = paths[i].slice(2);
+ entries[key] = stdout.trim().replace('\t\n', ',').split(',');
+ }
+ if (i === paths.length - 1) {
+ const text = 'export default ' + JSON.stringify(entries, null, ' ') + ';';
+ fs.writeFileSync('pages/helper/contributors.ts', text);
+ }
+ });
+ })(i);
+}
diff --git a/configs/config.js b/configs/config.js
index 7f29a80..2c2e1f6 100644
--- a/configs/config.js
+++ b/configs/config.js
@@ -1,5 +1,6 @@
export default {
rootPath: '/echarts-handbook/dist',
galleryViewPath: 'https://echarts.apache.org/examples/zh/view.html?c=',
- mainSitePath: 'https://echarts.apache.org/'
+ mainSitePath: 'https://echarts.apache.org/',
+ gitRepo: 'Ovilia/incubator-echarts-handbook'
};
diff --git a/contents/zh/chart-types/line.md b/contents/zh/chart-types/line.md
index 1424711..f2977ec 100644
--- a/contents/zh/chart-types/line.md
+++ b/contents/zh/chart-types/line.md
@@ -22,3 +22,5 @@ option = {
引用图片的方法:(这个图片实际存放地址在 `static/images/demo.png`)
![图片说明](${rootPath}/images/demo.png)
+
+sss
diff --git a/contents/zh/chart-types/xxx.md b/contents/zh/chart-types/xxx.md
new file mode 100644
index 0000000..e69de29
diff --git a/contents/zh/concepts/legend.md b/contents/zh/concepts/legend.md
new file mode 100644
index 0000000..e69de29
diff --git a/contents/zh/cookbook/downplay.md b/contents/zh/cookbook/downplay.md
new file mode 100644
index 0000000..e69de29
diff --git a/contents/zh/cookbook/mobile.md b/contents/zh/cookbook/mobile.md
new file mode 100644
index 0000000..e69de29
diff --git a/layouts/default.vue b/layouts/default.vue
index 730d495..ccf1095 100644
--- a/layouts/default.vue
+++ b/layouts/default.vue
@@ -42,10 +42,47 @@ export default Vue.extend({
</script>
<style>
-.post-content {
+.post-inner {
margin: 20px 0 80px 0;
}
+.post-content {
+ margin-bottom: 80px;
+}
+
+.post-contributors {
+ border-top: 1px solid #ddd;
+}
+
+.post-contributor {
+ display: inline-block;
+ border: 1px solid #eee;
+ border-radius: 5px;
+ color: #777;
+}
+
+.post-contributor:hover {
+ text-decoration: none;
+}
+
+.post-contributor img {
+ width: 30px;
+ height: 30px;
+ border-radius: 5px;
+ display: inline-block;
+}
+
+.post-contributor span {
+ display: inline-block;
+ margin: 0 8px 0 5px;
+ position: relative;
+ top: 2px;
+}
+
+.post-edit {
+ margin: 10px 0;
+}
+
h1 {
margin-bottom: 20px;
font-size: 36px;
diff --git a/package-lock.json b/package-lock.json
index eb72400..7ec43c2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1341,6 +1341,14 @@
"@types/webpack-bundle-analyzer": "^2.13.3",
"@types/webpack-dev-middleware": "^3.7.0",
"@types/webpack-hot-middleware": "^2.25.0"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "12.12.38",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.38.tgz",
+ "integrity": "sha512-75eLjX0pFuTcUXnnWmALMzzkYorjND0ezNEycaKesbUBg9eGZp4GHPuDmkRc4mQQvIpe29zrzATNRA6hkYqwmA==",
+ "dev": true
+ }
}
},
"@nuxt/typescript-build": {
@@ -1748,9 +1756,9 @@
"dev": true
},
"@types/node": {
- "version": "12.12.34",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.34.tgz",
- "integrity": "sha512-BneGN0J9ke24lBRn44hVHNeDlrXRYF+VRp0HbSUNnEZahXGAysHZIqnf/hER6aabdBgzM4YOV4jrR8gj4Zfi0g==",
+ "version": "13.13.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.5.tgz",
+ "integrity": "sha512-3ySmiBYJPqgjiHA7oEaIo2Rzz0HrOZ7yrNO5HWyaE5q0lQ3BppDZ3N53Miz8bw2I7gh1/zir2MGVZBvpb1zq9g==",
"dev": true
},
"@types/node-sass": {
diff --git a/package.json b/package.json
index 1af90e3..17752fa 100644
--- a/package.json
+++ b/package.json
@@ -8,6 +8,7 @@
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
+ "prepare": "node build/generate-contributors.js",
"generate": "nuxt generate",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore ."
},
diff --git a/pages/helper/contributors.ts b/pages/helper/contributors.ts
new file mode 100644
index 0000000..ff8b4c5
--- /dev/null
+++ b/pages/helper/contributors.ts
@@ -0,0 +1 @@
+export default {};
diff --git a/pages/helper/post.ts b/pages/helper/post.ts
index 0c82512..bc8b21b 100644
--- a/pages/helper/post.ts
+++ b/pages/helper/post.ts
@@ -2,6 +2,7 @@ import fm from 'front-matter';
import MarkdownIt from 'markdown-it';
import highlightjs from 'markdown-it-highlightjs';
import config from '../../configs/config';
+import contributors from './contributors';
export async function getPostData(path: string, lang: string) {
const md = new MarkdownIt({
@@ -9,8 +10,8 @@ export async function getPostData(path: string, lang: string) {
})
.use(highlightjs, {});
- path = path.split('_').join('/');
- const fileContent = await import(`~/contents/${lang}/${path}.md`);
+ const filePath = path.split('_').join('/');
+ const fileContent = await import(`~/contents/${lang}/${filePath}.md`);
let content = fileContent.default;
for (let attr in config) {
@@ -20,6 +21,8 @@ export async function getPostData(path: string, lang: string) {
const res = fm(content);
return {
attributes: res.attributes,
- content: md.render(res.body)
+ content: md.render(res.body),
+ contributors: contributors[`contents/${lang}/${filePath}.md`] || [],
+ sourcePath: `https://github.com/${config.gitRepo}/tree/master/contents/${lang}/${filePath}.md`
};
}
diff --git a/pages/zh/_post.vue b/pages/zh/_post.vue
index e1f0a89..f1f0289 100644
--- a/pages/zh/_post.vue
+++ b/pages/zh/_post.vue
@@ -1,5 +1,20 @@
<template>
- <div v-html="content" class="post-inner"></div>
+ <div>
+ <div v-html="content" class="post-inner"></div>
+
+ <div class="post-contributors">
+ <h3>本文贡献者</h3>
+ <div class="post-contributors-list" v-if="contributors.length">
+ <a v-for="contributor of contributors" :key="contributor" :href="`https://github.com/${contributor}`" target="_blank" class="post-contributor">
+ <img :alt="contributor" :src="`https://avatars.githubusercontent.com/${contributor}?size=60`">
+ <span>{{ contributor }}</span>
+ </a>
+ </div>
+ <div class="post-edit">
+ <a target="_blank" :href="sourcePath">编辑本文</a>
+ </div>
+ </div>
+ </div>
</template>
<script lang="ts">
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org