[U] Migrate to MDX

pull/27/head
Mak1o 2022-03-21 00:53:16 +08:00
parent 46e8bf3e8b
commit 92e43b18b0
14 changed files with 1602 additions and 89 deletions

View File

@ -1,47 +1,42 @@
# This is a basic workflow to help you get started with Actions
name: Generator
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [ main ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- name: Checkout
uses: actions/checkout@v2
- name: Setup Node
uses: actions/setup-node@v2
with:
python-version: "3.9"
- name: "Install dependencies"
node-version: 16.x
- name: Cache node_modules
uses: actions/cache@v2
id: cache
with:
path: node_modules
key: ${{ runner.os }}-node-${{ hashFiles('yarn.lock') }}
restore-keys: ${{ runner.os }}-node-
- name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: yarn install --production --frozen-lockfile
- name: Build
run: yarn build
- name: Deploy
run: |
set -xe
python -VV
python -m pip install json5
git config --global user.name $(git show -s --format='%an' HEAD)
git config --global user.email $(git show -s --format='%ae' HEAD)
- name: "Run generator"
run: "python generator.py"
- uses: EndBug/add-and-commit@v7
with:
# Determines the way the action fills missing author name and email. Three options are available:
# - github_actor -> UserName <UserName@users.noreply.github.com>
# - user_info -> Your Display Name <your-actual@email.com>
# - github_actions -> github-actions <email associated with the github logo>
# Default: github_actor
default_author: github_actions
# The message for the commit.
# Default: 'Commit from GitHub Actions (name of the workflow)'
message: '[U] Generate json'
cd dist
git init
git add .
git commit -m "Build on $(date '+%Y-%m-%d %H:%M:%S')"
git branch -m gh-pages
git remote add origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
git push -f origin gh-pages

6
.gitignore vendored
View File

@ -1,3 +1,9 @@
/dist
/node_modules
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.idea/inspectionProfiles/Project_Default.xml
.idea/misc.xml

View File

@ -16,5 +16,7 @@
* `photos`: Photo directory
* `comments`: List of comments made by other users in the format of `yyyy-mm-dd-{name}-{id}.txt`
* Directory `/generated`: Data that's automatically generated by Github Actions
* `people-list.json5`: A list of all people currently in the repository
* Branch `gh-pages`: Data that's automatically generated by Github Actions
* `people-list.json`: A list of all people currently in the repository
* Directory `/people/<userid>/`: Built data for a specific person
* `page.js`: `page.md` built with MDX

View File

@ -1,26 +0,0 @@
[
{
path: "Uekawakuyuurei",
id: "Uekawakuyuurei",
name: "蛍",
profileUrl: "${path}/photos/profile.jpg",
},
{
path: "gaoyanger",
id: "gaoyanger",
name: "羔羊",
profileUrl: "${path}/photos/profile.jpg",
},
{
path: "GLaDOSister",
id: "GLaDOSister",
name: "倉山静葉",
profileUrl: "${path}/photos/profile.jpg",
},
{
path: "donotexist_A",
id: "donotexist_A",
name: "不存在",
profileUrl: "${path}/photos/profile.jpg",
},
]

View File

@ -1,16 +0,0 @@
import io
import os, json5
from pathlib import Path
if __name__ == '__main__':
output = []
for p in os.listdir("people/"):
info_path = f'people/{p}/info.json5'
if os.path.isfile(info_path):
with io.open(info_path, 'r', encoding='utf-8') as f:
o = json5.load(f)
output.append({'path': p, 'id': o['id'], 'name': o['name'], 'profileUrl': o['profileUrl']})
Path("generated").mkdir(parents=True, exist_ok=True)
with io.open('generated/people-list.json5', 'w', encoding='utf-8') as f:
f.write(json5.dumps(output, indent=2, ensure_ascii=False))

26
package.json Normal file
View File

@ -0,0 +1,26 @@
{
"name": "our-data",
"version": "1.0.0",
"description": "Data for https://one-among.us",
"main": "scripts/build.ts",
"repository": "https://github.com/hykilpikonna/our-data",
"author": "Hykilpikonna <me@hydev.org>",
"license": "UNLICENSED",
"type": "module",
"private": true,
"scripts": {
"build": "node --loader ts-node/esm/transpile-only scripts/build.ts"
},
"dependencies": {
"@mdx-js/mdx": "^2.1.0",
"@swc/core": "^1.2.159",
"@types/fs-extra": "^9.0.13",
"@types/node": "^16",
"esbuild": "^0.14.27",
"fs-extra": "^10.0.1",
"json5": "^2.2.0",
"ts-node": "^10.7.0",
"typescript": "^4.6.2",
"xdm": "^3.4.0"
}
}

View File

@ -6,16 +6,16 @@
靠画作赞赏获得的收入是他的一部分经济来源。即使不幸确诊了升结肠印戒细胞癌,阿蛍也没有放下 ta 的画笔。后来,阿蛍把大部分画作的电子档上传到了 ta 的[Telegram频道](https://t.me/joinchat/65vSQ6ELb3YxN2I9),供大家无偿下载和欣赏。在这里挑选的几幅画作,可以让大家管窥阿蛍的绘画风格。
<PhotoScroll photos="[
'${path}/photos/IMG_1308.JPG',
'${path}/photos/img002.jpg',
'${path}/photos/img051.jpg',
'${path}/photos/img197.jpg',
'${path}/photos/img231.jpg',
'${path}/photos/img252.jpg',
'${path}/photos/img253.jpg',
'${path}/photos/img370.jpg',
]" />
<PhotoScroll photos={[
'${path}/photos/IMG_1308.JPG',
'${path}/photos/img002.jpg',
'${path}/photos/img051.jpg',
'${path}/photos/img197.jpg',
'${path}/photos/img231.jpg',
'${path}/photos/img252.jpg',
'${path}/photos/img253.jpg',
'${path}/photos/img370.jpg',
]} />
但这个世界就是这么不公平,阿蛍的病情持续恶化,并且一直没有找到合适的靶向药物。在 2021 年夏天,阿蛍被确诊为骨转移 IV 期。不过,即使承受着剧烈的疼痛,阿蛍仍然在关心和爱护着每一个安慰 ta 的推友,尽量不让我们担心。

View File

@ -2,9 +2,9 @@
存存是一个可爱的小姑娘,因此人缘也超级好,每一个见到存存的人都会被她的热情和开朗所打动。虽然存存患有双相以及其他的基础疾病,身体不是很好,经常生病[住院](https://twitter.com/donotexist_A/status/1383379769903910915?s=20),要吃很多药,但她和医生、病友的关系总是很好。同病房的美术生哥哥帮存存画过一张自画像。
<PhotoScroll photos="[
'${path}/photos/portrait.jpg',
]" />
<PhotoScroll photos={[
'${path}/photos/portrait.jpg',
]} />
因为存存常梳的发型有点像《动物森友会》里的西施惠,性格也跟西施惠一样可爱,所以有的时候我们也会叫她西施惠。可是存存自己好像有时候不喜欢我们这样叫。

View File

89
scripts/build.ts Normal file
View File

@ -0,0 +1,89 @@
import url from "url";
import path from "path";
import fs from "fs-extra";
import json5 from "json5";
import { renderMdx } from "./mdx.ts";
const PUBLIC_DIR = "public";
const PEOPLE_DIR = "people";
const PEOPLE_INFO_FILENAME = "info.json5";
const PEOPLE_PAGE_FILE = "page.md";
const DIST_DIR = "dist";
const DIST_PEOPLE_LIST = "people-list.json";
const DIST_PEOPLE_INFO_FILENAME = "info.json";
const DIST_PEOPLE_PAGE_FILE = "page.js";
const projectRoot = path.dirname(path.dirname(url.fileURLToPath(import.meta.url)));
const peopleDir = path.join(projectRoot, PEOPLE_DIR);
const people = fs.readdirSync(peopleDir).map(person => ({
dirname: person,
srcPath: path.join(peopleDir, person),
distPath: path.join(projectRoot, DIST_DIR, PEOPLE_DIR, person)
}));
// Transform `info.json5` to `info.json`.
// Extract metadata from `people/${dirname}/info.json5` to `dist/people-list.json`.
function buildPeopleInfoAndList() {
const PEOPLE_LIST_KEYS = ["id", "name", "profileUrl"] as const;
type PeopleMeta = Record<"path" | typeof PEOPLE_LIST_KEYS[number], unknown>;
const peopleList: PeopleMeta[] = [];
for (const { dirname, srcPath, distPath } of people) {
const infoFile = fs.readFileSync(path.join(srcPath, PEOPLE_INFO_FILENAME), "utf-8");
const info = json5.parse(infoFile);
const peopleMeta = {
path: dirname,
...Object.fromEntries(PEOPLE_LIST_KEYS.map(key => [key, info[key]]))
} as PeopleMeta;
peopleList.push(peopleMeta);
fs.ensureDirSync(distPath);
fs.writeFileSync(path.join(distPath, DIST_PEOPLE_INFO_FILENAME), JSON.stringify(info));
}
fs.writeFileSync(path.join(projectRoot, DIST_DIR, DIST_PEOPLE_LIST), JSON.stringify(peopleList));
}
// Render `people/${dirname}/page.md` to `dist/people/${dirname}/page.js`.
function buildPeoplePages() {
for (const { srcPath, distPath } of people) {
const markdown = fs.readFileSync(path.join(srcPath, PEOPLE_PAGE_FILE), "utf-8");
const result = renderMdx(markdown);
fs.ensureDirSync(distPath);
fs.writeFileSync(path.join(distPath, DIST_PEOPLE_PAGE_FILE), result);
}
}
// Copy `people/${dirname}/comments` and `photos` to `dist/people/${dirname}/`.
function copyPeopleAssets() {
const PEOPLE_ASSETS = ["comments", "photos"];
for (const { srcPath, distPath } of people) {
fs.ensureDirSync(distPath);
for (const assetDirname of PEOPLE_ASSETS) {
const assetSrcPath = path.join(srcPath, assetDirname);
if (fs.pathExistsSync(assetSrcPath)) {
fs.copySync(assetSrcPath, path.join(distPath, assetDirname));
}
}
}
}
// Copy files `public` to dist.
function copyPublic() {
fs.copySync(path.join(projectRoot, PUBLIC_DIR), path.join(projectRoot, DIST_DIR));
}
buildPeopleInfoAndList();
buildPeoplePages();
copyPeopleAssets();
copyPublic();

24
scripts/mdx.ts Normal file
View File

@ -0,0 +1,24 @@
import * as mdx from "xdm";
import * as swc from "@swc/core";
export function renderMdx(markdown: string): string {
const esmCode = mdx.compileSync(markdown, {
jsxRuntime: "classic",
pragma: "Vue.h",
pragmaFrag: "Vue.Fragment",
pragmaImportSource: "vue"
}).value.toString("utf-8");
const codeRemovedImport = esmCode.replace(/^import .*$/m, "");
return swc.transformSync(codeRemovedImport, {
jsc: {
parser: {
syntax: "ecmascript"
},
loose: true,
},
minify: true,
module: { type: "commonjs" },
}).code;
}

26
tsconfig.json Normal file
View File

@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "ES2021",
"lib": [
"ES2021"
],
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"strict": false,
"module": "ES2020",
"strictBindCallApply": true,
"baseUrl": "./",
"outDir": "./dist"
},
"include": [
"scripts"
],
"exclude": [
"node_modules",
"dist"
]
}

1387
yarn.lock Normal file

File diff suppressed because it is too large Load Diff