@tenjuu99/blog 0.1.3 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +7 -0
- package/README.md +9 -29
- package/bin/new +31 -0
- package/lib/config.js +32 -0
- package/lib/cssGenerator.js +2 -1
- package/lib/dir.js +4 -2
- package/lib/distribute.js +2 -1
- package/lib/filter.js +4 -2
- package/lib/indexer.js +27 -15
- package/lib/pageData.js +5 -4
- package/package.json +14 -4
- package/.env.prod.sample +0 -8
- package/.env.sample +0 -8
- package/.github/workflows/deploy.yml.sample +0 -51
- package/.github/workflows/github-page.yml +0 -52
- package/.gitignore +0 -9
- package/.node-version +0 -1
- package/helper/add.js +0 -3
- package/lib/replaceIfFilter.js +0 -67
- package/lib/replaceScriptFilter.js +0 -71
- package/performance.js +0 -22
- package/src-sample/pages/aaaa.md +0 -0
- package/src-sample/pages/aaaab.md +0 -0
- package/src-sample/pages/aaaac.md +0 -0
- package/src-sample/pages/aaaad.md +0 -0
- package/src-sample/pages/abc.md +0 -6
- package/src-sample/pages/fuga.md +0 -3
- package/src-sample/pages/hogehoge.md +0 -8
- package/src-sample/pages/hogehogehogehoge.md +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2024 Amashige Seiji
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
# blog template
|
|
2
2
|
|
|
3
|
-
##
|
|
4
|
-
|
|
5
|
-
以下のコマンドでプレビューできます。
|
|
3
|
+
## setup
|
|
6
4
|
|
|
7
5
|
```
|
|
8
|
-
npm
|
|
6
|
+
npm i @tenjuu99/blog
|
|
9
7
|
```
|
|
10
8
|
|
|
11
|
-
`http://localhost:8000/`
|
|
12
|
-
|
|
13
|
-
デフォルトでは8000ポートを利用しますが、環境変数を使ってポート番号を上書きできます。
|
|
14
|
-
|
|
15
9
|
```
|
|
16
|
-
|
|
10
|
+
npx create-blog
|
|
11
|
+
npx server
|
|
17
12
|
```
|
|
18
13
|
|
|
14
|
+
`http://localhost:8000` にアクセスできます
|
|
15
|
+
|
|
19
16
|
## 記事を書く
|
|
20
17
|
|
|
21
18
|
`./data/` 以下にマークダウンファイルを入稿します。
|
|
@@ -122,24 +119,7 @@ This is else content.
|
|
|
122
119
|
### SCRIPT
|
|
123
120
|
|
|
124
121
|
```markdown
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
122
|
+
<script type="ssg">
|
|
123
|
+
return 'これはスクリプトが実行された結果出力されました。'
|
|
124
|
+
</script>
|
|
128
125
|
```
|
|
129
|
-
|
|
130
|
-
## デプロイ
|
|
131
|
-
|
|
132
|
-
AWS S3 にデプロイするには、 `.github/workflow/deploy.yml.sample` を `.github/workflow/deploy.yml` にコピーします。
|
|
133
|
-
また、 `.env.prod` を作成して、以下の値を登録します。
|
|
134
|
-
|
|
135
|
-
```
|
|
136
|
-
SITE_NAME: テストサイト
|
|
137
|
-
URL_BASE: https://example.com
|
|
138
|
-
GTAG_ID: G-xxxx
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
GitHub のリポジトリで、`settings > Secrets and variables > Actions` から、以下の変数を登録します。
|
|
142
|
-
|
|
143
|
-
* `AWS_ACCESS_KEY_ID`
|
|
144
|
-
* `AWS_SECRET_ACCESS_KEY_ID`
|
|
145
|
-
* `S3_URL`
|
package/bin/new
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
mkdir -p "$(pwd)/src/pages"
|
|
4
|
+
echo "create src/pages"
|
|
5
|
+
mkdir -p "$(pwd)/src/template"
|
|
6
|
+
echo "create src/template"
|
|
7
|
+
mkdir -p "$(pwd)/src/css"
|
|
8
|
+
echo "create src/css"
|
|
9
|
+
mkdir -p "$(pwd)/src/image"
|
|
10
|
+
echo "create src/image"
|
|
11
|
+
|
|
12
|
+
mkdir "$(pwd)/.cache"
|
|
13
|
+
echo "[]" > "$(pwd)/.cache/index.json"
|
|
14
|
+
|
|
15
|
+
echo 'dist/*
|
|
16
|
+
node_modules/
|
|
17
|
+
.env
|
|
18
|
+
.cache
|
|
19
|
+
' >> .gitignore
|
|
20
|
+
|
|
21
|
+
echo '{
|
|
22
|
+
"site_name": "rewrite here",
|
|
23
|
+
"url_base": "http://localhost:8000",
|
|
24
|
+
"src_dir": "src",
|
|
25
|
+
"dist_dir": "dist",
|
|
26
|
+
"distribute_raw": "image",
|
|
27
|
+
"helper": "helper/index.js"
|
|
28
|
+
}' > "$(pwd)/blog.json"
|
|
29
|
+
echo "create blog.json"
|
|
30
|
+
|
|
31
|
+
cp -R "$(pwd)/node_modules/@tenjuu99/blog/src-sample/" "$(pwd)/src"
|
package/lib/config.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'node:fs'
|
|
2
|
+
|
|
3
|
+
const rootDir = process.cwd()
|
|
4
|
+
const config = {
|
|
5
|
+
"site_name": "default",
|
|
6
|
+
"url_base": "http://localhost:8000",
|
|
7
|
+
"src_dir": "src",
|
|
8
|
+
"dist_dir": "dist",
|
|
9
|
+
"distribute_raw": "image",
|
|
10
|
+
"relative_path": "",
|
|
11
|
+
"helper": ""
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
const file = rootDir + '/blog.json'
|
|
15
|
+
if (existsSync(file)) {
|
|
16
|
+
const configOverride = JSON.parse(readFileSync(file, 'utf8'))
|
|
17
|
+
for (const item in configOverride) {
|
|
18
|
+
config[item] = configOverride[item]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const keys = Object.keys(process.env)
|
|
22
|
+
for (const item in config) {
|
|
23
|
+
const upper = item.toUpperCase()
|
|
24
|
+
if (keys.includes(upper)) {
|
|
25
|
+
config[item] = process.env[upper]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
} catch (e) {
|
|
29
|
+
console.log(e)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default config
|
package/lib/cssGenerator.js
CHANGED
|
@@ -6,6 +6,7 @@ import path from 'path'
|
|
|
6
6
|
import { distDir as distRoot, cssDir } from './dir.js'
|
|
7
7
|
import { watchers } from './watcher.js'
|
|
8
8
|
import { styleText } from 'node:util'
|
|
9
|
+
import config from './config.js'
|
|
9
10
|
|
|
10
11
|
let cacheBuster = {}
|
|
11
12
|
const cacheBusterQuery = 't'
|
|
@@ -55,7 +56,7 @@ const applyCss = async (text) => {
|
|
|
55
56
|
})
|
|
56
57
|
for (const cssDist of target) {
|
|
57
58
|
const cacheBuster = await cssGenerator(cssDist.src, cssDist.dist)
|
|
58
|
-
text = text.replace(cssDist.matched, `${
|
|
59
|
+
text = text.replace(cssDist.matched, `${config.relative_path}${cssDist.dist}?${cacheBusterQuery}=${cacheBuster}`)
|
|
59
60
|
}
|
|
60
61
|
return text
|
|
61
62
|
}
|
package/lib/dir.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import config from './config.js'
|
|
2
|
+
|
|
1
3
|
const rootDir = process.cwd()
|
|
2
|
-
const srcDir = `${rootDir}/${
|
|
3
|
-
const distDir = `${rootDir}/${
|
|
4
|
+
const srcDir = `${rootDir}/${config.src_dir}`
|
|
5
|
+
const distDir = `${rootDir}/${config.dist_dir}`
|
|
4
6
|
const pageDir = `${srcDir}/pages`
|
|
5
7
|
const templateDir = `${srcDir}/template`
|
|
6
8
|
const cssDir = `${srcDir}/css`
|
package/lib/distribute.js
CHANGED
|
@@ -4,6 +4,7 @@ import path from 'path'
|
|
|
4
4
|
import { minifyHtml } from './minify.js'
|
|
5
5
|
import render from './render.js'
|
|
6
6
|
import { styleText } from 'node:util'
|
|
7
|
+
import config from './config.js'
|
|
7
8
|
|
|
8
9
|
const distribute = async (data, deleted, srcDir, distDir) => {
|
|
9
10
|
if (deleted) {
|
|
@@ -22,7 +23,7 @@ const distribute = async (data, deleted, srcDir, distDir) => {
|
|
|
22
23
|
console.log(styleText('green', '[generate]'), writeTo)
|
|
23
24
|
})
|
|
24
25
|
}
|
|
25
|
-
const distributeRaw =
|
|
26
|
+
const distributeRaw = config.distribute_raw.split(',')
|
|
26
27
|
distributeRaw.forEach((copyDir) => {
|
|
27
28
|
fs.readdir(`${srcDir}/${copyDir}/`).then(async files => {
|
|
28
29
|
await fs.stat(`${distDir}/${copyDir}/`).catch(async err => await fs.mkdir(`${distDir}/${copyDir}/`))
|
package/lib/filter.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as helper from '../helper/index.js'
|
|
2
2
|
import includeFilter from './includeFilter.js'
|
|
3
3
|
import { srcDir } from './dir.js'
|
|
4
|
+
import config from './config.js'
|
|
5
|
+
console.log(config)
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* @param {string} text
|
|
@@ -129,8 +131,8 @@ const replaceScriptFilter = async (text, variables) => {
|
|
|
129
131
|
for (const script of scripts) {
|
|
130
132
|
let helperMerged = {...helper}
|
|
131
133
|
// env.HELPER が定義されていれば追加ヘルパーとして扱う
|
|
132
|
-
if (
|
|
133
|
-
const additional = await import(`${srcDir}/${
|
|
134
|
+
if (config.helper) {
|
|
135
|
+
const additional = await import(`${srcDir}/${config.helper}`)
|
|
134
136
|
helperMerged = Object.assign(helperMerged, additional)
|
|
135
137
|
}
|
|
136
138
|
let result = new Function('helper', 'variables', script.script)(helperMerged, variables)
|
package/lib/indexer.js
CHANGED
|
@@ -1,30 +1,42 @@
|
|
|
1
1
|
"use strict"
|
|
2
|
-
import
|
|
2
|
+
import { writeFile, readFile } from "node:fs/promises";
|
|
3
|
+
import { readdirSync, existsSync, mkdirSync } from "node:fs";
|
|
3
4
|
import { pageDir, cacheDir } from './dir.js'
|
|
4
5
|
import makePageData from './pageData.js'
|
|
5
6
|
|
|
6
7
|
const indexFile = `${cacheDir}/index.json`
|
|
7
8
|
|
|
9
|
+
let newIndex = []
|
|
8
10
|
let allData = {}
|
|
9
11
|
let deleted = []
|
|
10
12
|
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
+
const collect = (dir, files = {}, namePrefix = '') => {
|
|
14
|
+
const dirents = readdirSync(dir, { withFileTypes: true })
|
|
15
|
+
dirents.forEach((dirent) => {
|
|
16
|
+
if (dirent.isDirectory()) {
|
|
17
|
+
collect(`${dirent.path}/${dirent.name}`, files, namePrefix + dirent.name + '/')
|
|
18
|
+
} else {
|
|
19
|
+
if (dirent.name.match(/\.(md|html)$/)) {
|
|
20
|
+
const pageData = makePageData(`${namePrefix}${dirent.name}`)
|
|
21
|
+
allData[pageData.name] = pageData
|
|
22
|
+
const { name, url, __output } = pageData
|
|
23
|
+
newIndex.push({ name, url, __output })
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
}
|
|
13
28
|
|
|
14
|
-
|
|
29
|
+
const indexing = async () => {
|
|
30
|
+
newIndex = []
|
|
15
31
|
allData = {}
|
|
16
32
|
deleted = []
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
newIndex.push({ name, url, __output })
|
|
25
|
-
})
|
|
26
|
-
})
|
|
27
|
-
fs.writeFile(indexFile, JSON.stringify(newIndex))
|
|
33
|
+
if (!existsSync(cacheDir)) {
|
|
34
|
+
mkdirSync(cacheDir)
|
|
35
|
+
}
|
|
36
|
+
const oldIndex = await readFile(indexFile, 'utf8').then(text => JSON.parse(text)).catch(error => [])
|
|
37
|
+
|
|
38
|
+
collect(pageDir)
|
|
39
|
+
writeFile(indexFile, JSON.stringify(newIndex))
|
|
28
40
|
|
|
29
41
|
// 旧インデックスから差分を計算して削除対象をピックアップする
|
|
30
42
|
deleted = oldIndex.filter(oi => !newIndex.map(ni => ni.__output).includes(oi.__output))
|
package/lib/pageData.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict"
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import { pageDir } from './dir.js'
|
|
4
|
+
import config from './config.js'
|
|
4
5
|
|
|
5
6
|
const load = (path) => {
|
|
6
7
|
return fs.readFileSync(path, 'utf8')
|
|
@@ -26,11 +27,11 @@ const parse = (content, name, ext) => {
|
|
|
26
27
|
index: true,
|
|
27
28
|
noindex: false,
|
|
28
29
|
lang: 'ja',
|
|
29
|
-
site_name:
|
|
30
|
-
url_base:
|
|
31
|
-
gtag_id:
|
|
30
|
+
site_name: config.site_name,
|
|
31
|
+
url_base: config.url_base,
|
|
32
|
+
gtag_id: config.gtag_id,
|
|
32
33
|
markdown: markdownReplaced,
|
|
33
|
-
relative_path:
|
|
34
|
+
relative_path: config.relative_path || '',
|
|
34
35
|
template: 'default.html',
|
|
35
36
|
ext: 'html',
|
|
36
37
|
__output: `/${name}.html`,
|
package/package.json
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tenjuu99/blog",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "blog template",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"dev": "
|
|
8
|
-
"generate": "
|
|
7
|
+
"dev": "node bin/server",
|
|
8
|
+
"generate": "node bin/generate",
|
|
9
9
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
10
10
|
},
|
|
11
11
|
"bin": {
|
|
12
12
|
"generate": "bin/generate",
|
|
13
|
-
"server": "bin/server"
|
|
13
|
+
"server": "bin/server",
|
|
14
|
+
"create-blog": "bin/new"
|
|
14
15
|
},
|
|
15
16
|
"author": "AmashigeSeiji",
|
|
16
17
|
"repository": {
|
|
@@ -25,5 +26,14 @@
|
|
|
25
26
|
"type": "module",
|
|
26
27
|
"engines": {
|
|
27
28
|
"node": ">=21.7"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"lib",
|
|
32
|
+
"bin",
|
|
33
|
+
"helper",
|
|
34
|
+
"src-sample"
|
|
35
|
+
],
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
28
38
|
}
|
|
29
39
|
}
|
package/.env.prod.sample
DELETED
package/.env.sample
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
name: Build html and deploy to S3
|
|
2
|
-
on:
|
|
3
|
-
push:
|
|
4
|
-
branches:
|
|
5
|
-
- main
|
|
6
|
-
jobs:
|
|
7
|
-
build:
|
|
8
|
-
runs-on: ubuntu-latest
|
|
9
|
-
steps:
|
|
10
|
-
- name: Checkout
|
|
11
|
-
uses: actions/checkout@master
|
|
12
|
-
|
|
13
|
-
- name: npm install
|
|
14
|
-
run: npm install --production
|
|
15
|
-
|
|
16
|
-
- name: Build
|
|
17
|
-
run: npm run generate:prod
|
|
18
|
-
|
|
19
|
-
- name: Deploy
|
|
20
|
-
env:
|
|
21
|
-
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
22
|
-
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
23
|
-
run: |
|
|
24
|
-
aws s3 sync \
|
|
25
|
-
--region ap-northeast-1 \
|
|
26
|
-
--exact-timestamps \
|
|
27
|
-
--exclude .gitignore \
|
|
28
|
-
--exclude '*.css' \
|
|
29
|
-
--exclude 'image/' \
|
|
30
|
-
--delete \
|
|
31
|
-
--metadata-directive REPLACE \
|
|
32
|
-
--cache-control "max-age=86400, no-cache, public" \
|
|
33
|
-
dist/ s3://${{ secrets.S3_URL }}/
|
|
34
|
-
|
|
35
|
-
aws s3 sync \
|
|
36
|
-
--region ap-northeast-1 \
|
|
37
|
-
--exact-timestamps \
|
|
38
|
-
--exclude .gitignore \
|
|
39
|
-
--delete \
|
|
40
|
-
--metadata-directive REPLACE \
|
|
41
|
-
--cache-control "max-age=31536000, public" \
|
|
42
|
-
dist/css/ s3://${{ secrets.S3_URL }}/css/
|
|
43
|
-
|
|
44
|
-
aws s3 sync \
|
|
45
|
-
--region ap-northeast-1 \
|
|
46
|
-
--exact-timestamps \
|
|
47
|
-
--exclude .gitignore \
|
|
48
|
-
--delete \
|
|
49
|
-
--metadata-directive REPLACE \
|
|
50
|
-
--cache-control "max-age=86400, public" \
|
|
51
|
-
dist/image/ s3://${{ secrets.S3_URL }}/image/
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
# Simple workflow for deploying static content to GitHub Pages
|
|
2
|
-
name: Deploy static content to Pages
|
|
3
|
-
|
|
4
|
-
on:
|
|
5
|
-
push:
|
|
6
|
-
branches:
|
|
7
|
-
- main
|
|
8
|
-
workflow_dispatch:
|
|
9
|
-
|
|
10
|
-
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
|
11
|
-
permissions:
|
|
12
|
-
contents: read
|
|
13
|
-
pages: write
|
|
14
|
-
id-token: write
|
|
15
|
-
|
|
16
|
-
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
|
17
|
-
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
|
18
|
-
concurrency:
|
|
19
|
-
group: "pages"
|
|
20
|
-
cancel-in-progress: false
|
|
21
|
-
|
|
22
|
-
jobs:
|
|
23
|
-
deploy:
|
|
24
|
-
environment:
|
|
25
|
-
name: github-pages
|
|
26
|
-
url: ${{ steps.deployment.outputs.page_url }}
|
|
27
|
-
runs-on: ubuntu-latest
|
|
28
|
-
steps:
|
|
29
|
-
- name: Checkout
|
|
30
|
-
uses: actions/checkout@master
|
|
31
|
-
|
|
32
|
-
- name: Use nodejs
|
|
33
|
-
uses: actions/setup-node@v4
|
|
34
|
-
with:
|
|
35
|
-
node-version: '22.x'
|
|
36
|
-
|
|
37
|
-
- name: npm install
|
|
38
|
-
run: npm install --omit=dev
|
|
39
|
-
|
|
40
|
-
- name: Build
|
|
41
|
-
run: cp .env.prod.sample .env && npm run generate
|
|
42
|
-
|
|
43
|
-
- name: Setup Pages
|
|
44
|
-
uses: actions/configure-pages@v4
|
|
45
|
-
- name: Upload artifact
|
|
46
|
-
uses: actions/upload-pages-artifact@v3
|
|
47
|
-
with:
|
|
48
|
-
# Upload dist
|
|
49
|
-
path: './dist/'
|
|
50
|
-
- name: Deploy to GitHub Pages
|
|
51
|
-
id: deployment
|
|
52
|
-
uses: actions/deploy-pages@v4
|
package/.gitignore
DELETED
package/.node-version
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
22.7.0
|
package/helper/add.js
DELETED
package/lib/replaceIfFilter.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @param {string} condition
|
|
3
|
-
* @params {object} variables
|
|
4
|
-
* @return {bool}
|
|
5
|
-
*/
|
|
6
|
-
const ifConditionEvaluator = (condition, variables) => {
|
|
7
|
-
if (condition.includes('=')) {
|
|
8
|
-
const segmented = condition.match(/(?<left>[\S]+)\s(?<operator>!=|==)\s(?<right>[\S]+)/)
|
|
9
|
-
let {left, operator, right} = segmented.groups
|
|
10
|
-
if (variables.hasOwnProperty(left)) {
|
|
11
|
-
left = variables[left]
|
|
12
|
-
} else {
|
|
13
|
-
try {
|
|
14
|
-
left = eval(left)
|
|
15
|
-
} catch (e) {
|
|
16
|
-
left = undefined
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
if (variables.hasOwnProperty(right)) {
|
|
20
|
-
right = variables[right]
|
|
21
|
-
} else {
|
|
22
|
-
try {
|
|
23
|
-
right = eval(right)
|
|
24
|
-
} catch (e) {
|
|
25
|
-
right = undefined
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
switch (operator) {
|
|
29
|
-
case '==':
|
|
30
|
-
return left == right
|
|
31
|
-
case '!=':
|
|
32
|
-
return left != right
|
|
33
|
-
}
|
|
34
|
-
} else {
|
|
35
|
-
if (variables.hasOwnProperty(condition)) {
|
|
36
|
-
return !!variables[condition]
|
|
37
|
-
}
|
|
38
|
-
return false
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const ifRegexp =
|
|
43
|
-
new RegExp(/(\{|<)if\s(?<condition>[\s\S]+?)(}|>)(?<content>[\s\S]*?)((\{|<)else(\}|>)(?<elsecontent>[\s\S]*?))?(\{<)\/if(>|})/g)
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* @param {string} text
|
|
47
|
-
* @param {object} variables
|
|
48
|
-
* @returns {string}
|
|
49
|
-
*/
|
|
50
|
-
const replaceIfFilter = (text, variables) => {
|
|
51
|
-
const matched = [...text.matchAll(ifRegexp)]
|
|
52
|
-
for (const item of matched) {
|
|
53
|
-
const target = item[0]
|
|
54
|
-
const content = item.groups.content
|
|
55
|
-
const elseContent = item.groups.elsecontent
|
|
56
|
-
if (ifConditionEvaluator(item.groups.condition, variables)) {
|
|
57
|
-
text = text.replace(target, content)
|
|
58
|
-
} else if (elseContent) {
|
|
59
|
-
text = text.replace(target, elseContent)
|
|
60
|
-
} else {
|
|
61
|
-
text = text.replace(target, '')
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return text
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export default replaceIfFilter
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import * as helper from '../helper/index.js'
|
|
2
|
-
import vm from 'vm'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 配列を再帰的に順不同リストに変換する
|
|
6
|
-
* @param {Array|string} arrayOrText
|
|
7
|
-
* @returns {mixed}
|
|
8
|
-
*/
|
|
9
|
-
const arrayToList = (arrayOrText) => {
|
|
10
|
-
if (typeof arrayOrText === 'string') {
|
|
11
|
-
return `<li>${arrayOrText}</li>`
|
|
12
|
-
}
|
|
13
|
-
if (Array.isArray(arrayOrText)) {
|
|
14
|
-
let resultListText = '<ul>'
|
|
15
|
-
for (const item of arrayOrText) {
|
|
16
|
-
if (Array.isArray(item)) {
|
|
17
|
-
resultListText += `<li>${arrayToList(item)}</li>`
|
|
18
|
-
} else {
|
|
19
|
-
resultListText += `<li>${item}</li>`
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
resultListText += '</ul>'
|
|
23
|
-
arrayOrText = resultListText
|
|
24
|
-
}
|
|
25
|
-
return arrayOrText
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const replaceScriptFilter = async (text, variables) => {
|
|
29
|
-
let replaced = text
|
|
30
|
-
const scriptRegexp = new RegExp(/({script}|\<script\s.*type="ssg".*>)(?<script>[\s\S]*?)(\{\/script}|\<\/script>)/g)
|
|
31
|
-
const scripts = [...text.matchAll(scriptRegexp)].map((matched) => {
|
|
32
|
-
return {
|
|
33
|
-
replace: matched[0],
|
|
34
|
-
script: matched.groups.script.trim("\n"),
|
|
35
|
-
}
|
|
36
|
-
})
|
|
37
|
-
const context = vm.createContext({
|
|
38
|
-
helper,
|
|
39
|
-
variables,
|
|
40
|
-
})
|
|
41
|
-
for (const script of scripts) {
|
|
42
|
-
const s = new vm.Script(script.script)
|
|
43
|
-
console.log(script.script)
|
|
44
|
-
console.log(s)
|
|
45
|
-
console.log('------------------------------------------------')
|
|
46
|
-
const func = vm.runInContext(script, context)
|
|
47
|
-
console.log(func)
|
|
48
|
-
let result = await func(variables, helper)
|
|
49
|
-
if (result instanceof Promise) {
|
|
50
|
-
result = await result
|
|
51
|
-
}
|
|
52
|
-
if (Array.isArray(result)) {
|
|
53
|
-
result = arrayToList(result)
|
|
54
|
-
} else if (typeof result === 'object') {
|
|
55
|
-
const resultText = []
|
|
56
|
-
for (const key in result) {
|
|
57
|
-
resultText.push(`<h3>${key}</h3>`)
|
|
58
|
-
if (Array.isArray(result[key])) {
|
|
59
|
-
resultText.push(arrayToList(result[key]))
|
|
60
|
-
} else {
|
|
61
|
-
resultText.push(`<p>${result[key]}</p>`)
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
result = resultText.join('\n')
|
|
65
|
-
}
|
|
66
|
-
replaced = replaced.replace(script.replace, result)
|
|
67
|
-
}
|
|
68
|
-
return replaced
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export default replaceScriptFilter
|
package/performance.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict"
|
|
2
|
-
import distribute from './lib/distribute.js'
|
|
3
|
-
import { indexing, allData, deleted } from './lib/indexer.js'
|
|
4
|
-
import { srcDir, distDir } from './lib/dir.js'
|
|
5
|
-
|
|
6
|
-
process.env.FORCE_BUILD = true
|
|
7
|
-
const doBuild = async () => {
|
|
8
|
-
const start = performance.now()
|
|
9
|
-
await indexing()
|
|
10
|
-
await distribute(allData, deleted, srcDir, distDir)
|
|
11
|
-
const end = performance.now()
|
|
12
|
-
return end - start
|
|
13
|
-
}
|
|
14
|
-
const times = 100
|
|
15
|
-
let executed = 0
|
|
16
|
-
for (let i = 0; i < times; i++) {
|
|
17
|
-
// console.log(await executed())
|
|
18
|
-
const buildTime = await doBuild()
|
|
19
|
-
executed += (buildTime)
|
|
20
|
-
console.log(buildTime)
|
|
21
|
-
}
|
|
22
|
-
console.log('build average: 100 times: ' + (executed/times) + "ms")
|
package/src-sample/pages/aaaa.md
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src-sample/pages/abc.md
DELETED
package/src-sample/pages/fuga.md
DELETED
|
File without changes
|