@tenjuu99/blog 0.1.6 → 0.1.8
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/README.md +52 -82
- package/lib/filter.js +14 -17
- package/lib/helper.js +12 -0
- package/lib/render.js +1 -0
- package/package.json +1 -1
- package/src-sample/pages/sample.md +3 -7
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# blog
|
|
1
|
+
# @tenjuu99/blog
|
|
2
2
|
|
|
3
3
|
## setup
|
|
4
4
|
|
|
@@ -15,111 +15,81 @@ npx server
|
|
|
15
15
|
|
|
16
16
|
## 記事を書く
|
|
17
17
|
|
|
18
|
-
`./
|
|
18
|
+
`./src/pages/` 以下にマークダウンファイルを入稿します。
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
`
|
|
22
|
-
`url` は出力先になります。
|
|
23
|
-
`published` は index ファイルがソートするのに利用します。
|
|
20
|
+
とりあえずなにも設定せずに、内容は空のままで構わないので `src/pages/test.md` を追加してみます。
|
|
21
|
+
`src/pages/test.md` を保存したら、 `http://localhost:8000/test` にアクセスして表示できていることを確認します。
|
|
24
22
|
|
|
25
|
-
|
|
23
|
+
次に、内容を記述します。
|
|
24
|
+
`src/pages/test.md` を次のような内容で保存します。
|
|
26
25
|
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
title: sample article
|
|
30
|
-
url: /sample_article
|
|
31
|
-
published: 2024/03/18 00:00
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
トップレベル見出しは `title` 変数が利用されます。
|
|
35
|
-
変えたい場合は template/default.html を修正してください。
|
|
26
|
+
```
|
|
27
|
+
# 第一章 人情の碗
|
|
36
28
|
|
|
37
|
-
|
|
29
|
+
茶は薬用として始まり後飲料となる。シナにおいては八世紀に高雅な遊びの一つとして詩歌の域に達した。十五世紀に至り日本はこれを高めて一種の審美的宗教、すなわち茶道にまで進めた。茶道は日常生活の俗事の中に存する美しきものを崇拝することに基づく一種の儀式であって、純粋と調和、相互愛の神秘、社会秩序のローマン主義を諄々と教えるものでる。茶道の要義は「不完全なもの」を崇拝するにある。いわゆる人生というこの不可解なもののうちに、何か可能なものを成就しようとするやさしい企てであるから。
|
|
30
|
+
```
|
|
38
31
|
|
|
39
|
-
|
|
32
|
+
保存したら、 `http://localhost:8000/test` をリロードして表示を確認しましょう。
|
|
40
33
|
|
|
41
|
-
##
|
|
34
|
+
## タイトルとURL
|
|
42
35
|
|
|
43
|
-
|
|
36
|
+
ファイル冒頭を `---` でくくると変数を指定できます。
|
|
44
37
|
|
|
45
|
-
|
|
46
|
-
[アンカーテキストはこちら](http://example.com)
|
|
38
|
+
`src/pages/test.md` の冒頭に次のような変数を設定してみましょう。
|
|
47
39
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
40
|
+
```markdown
|
|
41
|
+
---
|
|
42
|
+
title: 第一章 人情の碗
|
|
43
|
+
url: /the_book_of_tea/section_one
|
|
44
|
+
---
|
|
45
|
+
```
|
|
52
46
|
|
|
53
|
-
|
|
47
|
+
`http://localhost:8000/test` ではアクセスできず、 `http://localhost:8000/the_book_of_tea/section_one` でアクセスできるようになったとおもいます。
|
|
54
48
|
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
ここで定義した変数は、テンプレート内でも利用できます。
|
|
50
|
+
次のように書き換えてみます。
|
|
57
51
|
|
|
58
|
-

|
|
59
52
|
|
|
60
|
-
|
|
53
|
+
```markdown
|
|
54
|
+
---
|
|
55
|
+
title: 第一章 人情の碗
|
|
56
|
+
url: /the_book_of_tea/section_one
|
|
57
|
+
---
|
|
61
58
|
|
|
62
|
-
|
|
59
|
+
# {{title}}
|
|
63
60
|
|
|
64
|
-
|
|
65
|
-
return (new Date()).toString()
|
|
66
|
-
{/script}
|
|
61
|
+
茶は薬用として始まり後飲料となる。シナにおいては八世紀に高雅な遊びの一つとして詩歌の域に達した。十五世紀に至り日本はこれを高めて一種の審美的宗教、すなわち茶道にまで進めた。茶道は日常生活の俗事の中に存する美しきものを崇拝することに基づく一種の儀式であって、純粋と調和、相互愛の神秘、社会秩序のローマン主義を諄々と教えるものでる。茶道の要義は「不完全なもの」を崇拝するにある。いわゆる人生というこの不可解なもののうちに、何か可能なものを成就しようとするやさしい企てであるから。
|
|
67
62
|
```
|
|
68
63
|
|
|
69
|
-
|
|
64
|
+
URLの変更は、変数による定義ではなく、ファイルを移動しても問題ありません。
|
|
65
|
+
`src/pages/test.md` を `src/pages/the_book_of_tea/section_one.md` としてファイルを移動すれば、変数定義がなくてもこのURLになります。
|
|
70
66
|
|
|
71
|
-
##
|
|
67
|
+
## テンプレート
|
|
72
68
|
|
|
73
|
-
|
|
69
|
+
タイトルが重複して表示されて鬱陶しいので、テンプレートを編集します。
|
|
74
70
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
```markdown
|
|
78
|
-
---
|
|
79
|
-
foo: fooVariableContent
|
|
80
|
-
bar: varVariableContent
|
|
81
|
-
---
|
|
82
|
-
```
|
|
71
|
+
`src/template/default.html` を開き、h1 を削除しましょう。
|
|
83
72
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
<!DOCTYPE html>
|
|
88
|
-
<html lang="en">
|
|
89
|
-
<head>
|
|
90
|
-
<meta charset="UTF-8">
|
|
91
|
-
<title></title>
|
|
92
|
-
</head>
|
|
93
|
-
<body>
|
|
94
|
-
{{foo}}
|
|
95
|
-
{{bar}}
|
|
96
|
-
</body>
|
|
97
|
-
</html>
|
|
73
|
+
```diff
|
|
74
|
+
<article class="container">
|
|
75
|
+
- <h1>{{TITLE}}</h1>
|
|
98
76
|
```
|
|
99
77
|
|
|
100
|
-
|
|
78
|
+
## 設定ファイル
|
|
101
79
|
|
|
102
|
-
|
|
80
|
+
サイト全体の名称がデフォルトのままでは味気ないので変えましょう。
|
|
81
|
+
blog.json を開いて、 `site_name` を変更します。
|
|
103
82
|
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
This content will be removed.
|
|
114
|
-
{else}
|
|
115
|
-
This is else content.
|
|
116
|
-
{/if}
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"site_name": "茶の本",
|
|
86
|
+
"url_base": "http://localhost:8000",
|
|
87
|
+
"src_dir": "src",
|
|
88
|
+
"dist_dir": "dist",
|
|
89
|
+
"distribute_raw": "image",
|
|
90
|
+
"helper": "helper/index.js"
|
|
91
|
+
}
|
|
117
92
|
```
|
|
118
93
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
```markdown
|
|
122
|
-
<script type="ssg">
|
|
123
|
-
return 'これはスクリプトが実行された結果出力されました。'
|
|
124
|
-
</script>
|
|
125
|
-
```
|
|
94
|
+
設定ファイルを変更したら、一旦 `CTRL+c` で `npx server` を停止して、もういちど `npx server` を実行します。
|
|
95
|
+
ヘッダーが「茶の本」になっていたら設定更新が完了です。
|
package/lib/filter.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import helper from '../lib/helper.js'
|
|
2
2
|
import includeFilter from './includeFilter.js'
|
|
3
3
|
import { srcDir } from './dir.js'
|
|
4
4
|
import config from './config.js'
|
|
5
|
-
console.log(config)
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* @param {string} text
|
|
@@ -10,19 +9,23 @@ console.log(config)
|
|
|
10
9
|
* @return {text}
|
|
11
10
|
*/
|
|
12
11
|
const replaceVariablesFilter = (text, variables) => {
|
|
13
|
-
const matched = [...text.matchAll(/{{\s?([\w\d
|
|
14
|
-
const replace = Object.fromEntries(matched.map(match => [match[
|
|
12
|
+
const matched = [...text.matchAll(/(\\)?{{\s?([\w\d\s,-_\(\)]+)\s?}}/g)]
|
|
13
|
+
const replace = Object.fromEntries(matched.map(match => [match[2].toLowerCase(), {replace: match[0], backslash: match[1]}]))
|
|
15
14
|
let replaced = text
|
|
16
15
|
for (const elm in replace) {
|
|
17
|
-
const toBeReplace = replace[elm]
|
|
18
|
-
const toBeReplaceScript = toBeReplace.match(/([\w\d_
|
|
19
|
-
|
|
16
|
+
const toBeReplace = replace[elm].replace
|
|
17
|
+
const toBeReplaceScript = toBeReplace.match(/([\w\d_]+)\((.*)\)/)
|
|
18
|
+
|
|
19
|
+
if (replace[elm].backslash) { // escape variable syntax
|
|
20
|
+
const removeBackslash = replace[elm].replace.replace(/\\/, '')
|
|
21
|
+
replaced = replaced.replaceAll(toBeReplace, removeBackslash)
|
|
22
|
+
} else if (toBeReplaceScript) { // execute helper
|
|
20
23
|
const func = toBeReplaceScript[1]
|
|
21
|
-
const
|
|
24
|
+
const args = toBeReplaceScript[2].split(',').map(v => variables[v.trim()] ?? undefined)
|
|
22
25
|
if (!helper[func]) {
|
|
23
|
-
throw new
|
|
26
|
+
throw new Error('helper function is missing. function name: ' + func);
|
|
24
27
|
}
|
|
25
|
-
const replaceText = helper[func]
|
|
28
|
+
const replaceText = helper[func].call(null, ...args)
|
|
26
29
|
replaced = replaced.replaceAll(toBeReplace, replaceText)
|
|
27
30
|
} else {
|
|
28
31
|
replaced = replaced.replaceAll(toBeReplace, variables[elm])
|
|
@@ -129,13 +132,7 @@ const replaceScriptFilter = async (text, variables) => {
|
|
|
129
132
|
}
|
|
130
133
|
})
|
|
131
134
|
for (const script of scripts) {
|
|
132
|
-
let
|
|
133
|
-
// env.HELPER が定義されていれば追加ヘルパーとして扱う
|
|
134
|
-
if (config.helper) {
|
|
135
|
-
const additional = await import(`${srcDir}/${config.helper}`)
|
|
136
|
-
helperMerged = Object.assign(helperMerged, additional)
|
|
137
|
-
}
|
|
138
|
-
let result = new Function('helper', 'variables', script.script)(helperMerged, variables)
|
|
135
|
+
let result = new Function('helper', 'variables', script.script)(helper, variables)
|
|
139
136
|
if (result instanceof Promise) {
|
|
140
137
|
result = await result
|
|
141
138
|
}
|
package/lib/helper.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as helperDefault from '../helper/index.js'
|
|
2
|
+
import config from './config.js'
|
|
3
|
+
import { srcDir } from './dir.js'
|
|
4
|
+
|
|
5
|
+
let helper = {...helperDefault}
|
|
6
|
+
|
|
7
|
+
if (config['helper']) {
|
|
8
|
+
const helperAdditional = await import(`${srcDir}/${config.helper}`)
|
|
9
|
+
helper = Object.assign(helper, helperAdditional)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default helper
|
package/lib/render.js
CHANGED
|
@@ -16,6 +16,7 @@ const render = async (templateName, data) => {
|
|
|
16
16
|
markdown = await includeFilter(markdown)
|
|
17
17
|
markdown = await replaceIfFilter(markdown, data)
|
|
18
18
|
markdown = await replaceScriptFilter(markdown, data)
|
|
19
|
+
markdown = replaceVariablesFilter(markdown, data)
|
|
19
20
|
data.markdown = data.__filetype === 'md' ? marked.parse(markdown) : markdown
|
|
20
21
|
|
|
21
22
|
return replaceVariablesFilter(template, data)
|
package/package.json
CHANGED
|
@@ -113,7 +113,7 @@ return variables.someVariable
|
|
|
113
113
|
{/script}
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
-
##
|
|
116
|
+
## ヘルパー
|
|
117
117
|
|
|
118
118
|
ヘルパー関数を作成します。
|
|
119
119
|
```
|
|
@@ -132,14 +132,10 @@ HELPER=helper/index.js
|
|
|
132
132
|
追加したヘルパーを利用できます。
|
|
133
133
|
<pre>
|
|
134
134
|
// src-sample/pages/sample.md
|
|
135
|
-
|
|
136
|
-
return helper.additionalHelper()
|
|
137
|
-
</script>
|
|
135
|
+
\{{ additionalHelper() }}
|
|
138
136
|
</pre>
|
|
139
137
|
|
|
140
138
|
実際に出力させると次の行のとおりです。
|
|
141
139
|
```
|
|
142
|
-
|
|
143
|
-
return helper.additionalHelper()
|
|
144
|
-
</script>
|
|
140
|
+
{{additionalHelper()}}
|
|
145
141
|
```
|