@tenjuu99/blog 0.2.7 → 0.2.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/bin/new +1 -10
- package/lib/helper.js +8 -6
- package/lib/tryServer.js +3 -0
- package/package.json +1 -1
- package/src-sample/css/editor.css +50 -35
- package/src-sample/helper/index.js +115 -0
- package/src-sample/js/editor.js +6 -0
- package/src-sample/js/error.js +1 -0
- package/src-sample/template/editor.html +22 -24
- package/helper/index.js +0 -116
package/bin/new
CHANGED
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
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
3
|
mkdir "$(pwd)/.cache"
|
|
13
4
|
echo "[]" > "$(pwd)/.cache/index.json"
|
|
14
5
|
|
|
@@ -24,7 +15,7 @@ echo '{
|
|
|
24
15
|
"src_dir": "src",
|
|
25
16
|
"dist_dir": "dist",
|
|
26
17
|
"distribute_raw": "image,js",
|
|
27
|
-
"helper": "
|
|
18
|
+
"helper": "index.js",
|
|
28
19
|
"editor_enable": true
|
|
29
20
|
}' > "$(pwd)/blog.json"
|
|
30
21
|
echo "create blog.json"
|
package/lib/helper.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import * as helperDefault from '../helper/index.js'
|
|
2
1
|
import config from './config.js'
|
|
3
|
-
import {
|
|
2
|
+
import { helperDir } from './dir.js'
|
|
4
3
|
|
|
5
|
-
let helper = {
|
|
4
|
+
let helper = {}
|
|
6
5
|
|
|
7
|
-
if (config
|
|
8
|
-
const
|
|
9
|
-
|
|
6
|
+
if (config.helper) {
|
|
7
|
+
const files = config.helper.split(',')
|
|
8
|
+
files.forEach(async file => {
|
|
9
|
+
const helperAdditional = await import(`${helperDir}/${file}`)
|
|
10
|
+
helper = Object.assign(helper, helperAdditional)
|
|
11
|
+
})
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
export default helper
|
package/lib/tryServer.js
CHANGED
|
@@ -22,6 +22,9 @@ const handlers = async (path) => {
|
|
|
22
22
|
* @param {http.ServerResponse} res
|
|
23
23
|
*/
|
|
24
24
|
const tryServer = async (path, req, res) => {
|
|
25
|
+
if (!fs.existsSync(serverDir)) {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
25
28
|
const handler = await handlers(path)
|
|
26
29
|
const method = req.method.toLowerCase()
|
|
27
30
|
if (handler && handler[method]) {
|
package/package.json
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
body {
|
|
2
2
|
background: #fafafa;
|
|
3
|
-
--container-max-width: 100%;
|
|
4
|
-
--container-min-width: 100%;
|
|
5
|
-
--container-width: 100%;
|
|
6
3
|
height: 100vh;
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
}
|
|
7
|
+
header {
|
|
8
|
+
text-align: center;
|
|
9
|
+
border-bottom: .1px solid #eee;
|
|
10
|
+
box-shadow: 1px 1px 3px #999;
|
|
7
11
|
}
|
|
8
12
|
main {
|
|
9
13
|
height: 100%;
|
|
10
|
-
margin: 0 auto
|
|
14
|
+
/*margin: 0 auto;*/
|
|
11
15
|
display: flex;
|
|
12
16
|
flex-direction: row;
|
|
13
17
|
justify-content: flex-start;
|
|
@@ -17,7 +21,7 @@ main.container {
|
|
|
17
21
|
}
|
|
18
22
|
.textareaAndPreview {
|
|
19
23
|
display: flex;
|
|
20
|
-
margin:
|
|
24
|
+
margin: 0;
|
|
21
25
|
border: 1px solid #666;
|
|
22
26
|
border-radius: 5px;
|
|
23
27
|
height: 100%;
|
|
@@ -28,19 +32,23 @@ main.container {
|
|
|
28
32
|
.editor {
|
|
29
33
|
display: flex;
|
|
30
34
|
flex-direction: column;
|
|
31
|
-
padding:
|
|
35
|
+
padding: 5px;
|
|
32
36
|
justify-content:center;
|
|
33
37
|
height: 100%;
|
|
34
38
|
/* width: 100%; */
|
|
35
|
-
margin: 0
|
|
39
|
+
margin: 0;
|
|
36
40
|
position: relative;
|
|
41
|
+
width: 100%;
|
|
37
42
|
left: 0;
|
|
38
43
|
flex-basis: 100%;
|
|
39
|
-
transition: flex-basis 0.3s;
|
|
40
44
|
}
|
|
41
45
|
.sidebar-close .editor {
|
|
42
|
-
flex-basis: 90
|
|
43
|
-
|
|
46
|
+
/*flex-basis: 90%;*/
|
|
47
|
+
margin-left: 20px;
|
|
48
|
+
}
|
|
49
|
+
.editor-options {
|
|
50
|
+
display: flex;
|
|
51
|
+
justify-content: space-between;
|
|
44
52
|
}
|
|
45
53
|
#editorTextArea {
|
|
46
54
|
resize: none;
|
|
@@ -58,7 +66,6 @@ main.container {
|
|
|
58
66
|
}
|
|
59
67
|
form select {
|
|
60
68
|
padding: 5px;
|
|
61
|
-
margin-top: 5px;
|
|
62
69
|
border-radius: 5px;
|
|
63
70
|
}
|
|
64
71
|
#previewContent {
|
|
@@ -80,64 +87,55 @@ form select {
|
|
|
80
87
|
width: 300px;
|
|
81
88
|
overflow: hidden;
|
|
82
89
|
left: 0;
|
|
83
|
-
background:
|
|
90
|
+
background: rgb(192, 198, 217);
|
|
84
91
|
height: 100%;
|
|
85
92
|
padding: 0;
|
|
86
93
|
overflow-y: hidden;
|
|
87
|
-
transition: left 0.3s, flex-basis 0.3s;
|
|
88
94
|
flex-basis: 300px;
|
|
89
95
|
position: relative;
|
|
96
|
+
z-index: 3;
|
|
97
|
+
word-break: break-all;
|
|
90
98
|
}
|
|
91
99
|
.sidebar-close .sidebar {
|
|
92
100
|
left: -290px;
|
|
93
|
-
transition: left 0.3s, flex-basis 0.3s;
|
|
94
101
|
flex-basis: 0;
|
|
95
102
|
}
|
|
96
103
|
.sidebar ul {
|
|
97
104
|
padding: 0;
|
|
98
|
-
margin: 0
|
|
99
|
-
left: 0;
|
|
100
|
-
transition: left 0.3s;
|
|
101
|
-
min-width: 180px;
|
|
102
|
-
max-width: 180px;
|
|
105
|
+
margin: 0;
|
|
103
106
|
}
|
|
104
107
|
.sidebar-close .sidebar ul {
|
|
105
108
|
position: absolute;
|
|
106
109
|
left: -290px;
|
|
107
110
|
transition: left 0.3s;
|
|
108
111
|
}
|
|
109
|
-
@media screen and (min-width: 1100px) {
|
|
110
|
-
}
|
|
111
|
-
@media screen and (min-width: 1400px) {
|
|
112
|
-
}
|
|
113
|
-
@media screen and (max-width: 600px) {
|
|
114
|
-
.sidebar {
|
|
115
|
-
flex-basis: 80%;
|
|
116
|
-
}
|
|
117
|
-
.sidebar.close {
|
|
118
|
-
flex-basis: 5%;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
112
|
.sidebar li {
|
|
122
113
|
list-style: none;
|
|
114
|
+
padding-left: 20px;
|
|
123
115
|
}
|
|
124
116
|
.sidebar a {
|
|
125
|
-
color: #
|
|
117
|
+
color: #666;
|
|
118
|
+
text-decoration: none;
|
|
119
|
+
}
|
|
120
|
+
.sidebar li:hover {
|
|
121
|
+
background: rgba(104, 117, 154, .3);
|
|
126
122
|
}
|
|
127
123
|
.sidebar-toggle {
|
|
128
124
|
cursor: pointer;
|
|
129
125
|
width: 20px;
|
|
130
126
|
height: 100%;
|
|
131
|
-
|
|
127
|
+
position: absolute;
|
|
128
|
+
right: 0;
|
|
132
129
|
}
|
|
133
130
|
.sidebar-close .sidebar-toggle {
|
|
134
131
|
position: fixed;
|
|
135
132
|
left: 0;
|
|
133
|
+
background: rgb(192, 198, 217);
|
|
136
134
|
}
|
|
137
135
|
.sidebar-toggle:hover:after {
|
|
138
136
|
position: absolute;
|
|
139
137
|
right: 0;
|
|
140
|
-
content: '
|
|
138
|
+
content: '';
|
|
141
139
|
height: 100%;
|
|
142
140
|
width: 20px;
|
|
143
141
|
background: rgba(255, 255,255, 0.3);
|
|
@@ -177,6 +175,12 @@ form select {
|
|
|
177
175
|
.sidebar-toggle {
|
|
178
176
|
display: none;
|
|
179
177
|
}
|
|
178
|
+
.sidebar {
|
|
179
|
+
flex-basis: 80%;
|
|
180
|
+
}
|
|
181
|
+
.sidebar.close {
|
|
182
|
+
flex-basis: 5%;
|
|
183
|
+
}
|
|
180
184
|
}
|
|
181
185
|
/**
|
|
182
186
|
* hamburger
|
|
@@ -185,6 +189,17 @@ form select {
|
|
|
185
189
|
display: none;
|
|
186
190
|
}
|
|
187
191
|
@media screen and (max-width: 600px) {
|
|
192
|
+
.sidebar-close .editor {
|
|
193
|
+
margin-left: 0;
|
|
194
|
+
margin: 0;
|
|
195
|
+
}
|
|
196
|
+
.editor-options {
|
|
197
|
+
margin-right: 50px;
|
|
198
|
+
}
|
|
199
|
+
.editor-options * {
|
|
200
|
+
display: flex;
|
|
201
|
+
flex-direction: column;
|
|
202
|
+
}
|
|
188
203
|
.hamburger-menu {
|
|
189
204
|
display: block;
|
|
190
205
|
}
|
|
@@ -208,7 +223,7 @@ form select {
|
|
|
208
223
|
height: 3px;
|
|
209
224
|
width: 25px;
|
|
210
225
|
border-radius: 3px;
|
|
211
|
-
background-color: #
|
|
226
|
+
background-color: #666666;
|
|
212
227
|
position: absolute;
|
|
213
228
|
transition: transform 0.3s, background-color 0.3s;
|
|
214
229
|
}
|
|
@@ -1,4 +1,119 @@
|
|
|
1
1
|
import { allData } from '@tenjuu99/blog/lib/indexer.js'
|
|
2
|
+
import { replaceVariablesFilter } from "@tenjuu99/blog/lib/filter.js";
|
|
3
|
+
import config from '@tenjuu99/blog/lib/config.js'
|
|
4
|
+
|
|
5
|
+
export function readIndex (filter = null) {
|
|
6
|
+
const data = Object.entries(allData)
|
|
7
|
+
.sort((a, b) => new Date(b[1].published) - new Date(a[1].published))
|
|
8
|
+
return filter
|
|
9
|
+
? data.filter(v => v[0].indexOf(filter) === 0).map(v => v[1])
|
|
10
|
+
: data.map(v => v[1])
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function dateFormat(dateString) {
|
|
14
|
+
const date = new Date(dateString)
|
|
15
|
+
return `${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日`
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function render(text, variables) {
|
|
19
|
+
return replaceVariablesFilter(text, variables)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function getPageData(name) {
|
|
23
|
+
return allData[name]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let indexedItemsSorted = null
|
|
27
|
+
export function indexedItems() {
|
|
28
|
+
if (indexedItemsSorted) {
|
|
29
|
+
return indexedItemsSorted
|
|
30
|
+
}
|
|
31
|
+
const sorted = readIndex()
|
|
32
|
+
.filter(v => v.index && v.published != '1970-01-01')
|
|
33
|
+
.sort((a, b) => new Date(a.published) - new Date(b.published))
|
|
34
|
+
let prev, next
|
|
35
|
+
for (const item of sorted) {
|
|
36
|
+
if (prev) {
|
|
37
|
+
prev.next = {
|
|
38
|
+
name: item.name,
|
|
39
|
+
published: item.published,
|
|
40
|
+
url: item.url,
|
|
41
|
+
title: item.title,
|
|
42
|
+
}
|
|
43
|
+
item.prev = {
|
|
44
|
+
name: prev.name,
|
|
45
|
+
published: prev.published,
|
|
46
|
+
url: prev.url,
|
|
47
|
+
title: prev.title,
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
prev = item
|
|
51
|
+
}
|
|
52
|
+
indexedItemsSorted = sorted
|
|
53
|
+
return indexedItemsSorted
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 配列を再帰的に順不同リストに変換する
|
|
58
|
+
* @param {Array|string} arrayOrText
|
|
59
|
+
* @returns {mixed}
|
|
60
|
+
*/
|
|
61
|
+
export function arrayToList(arrayOrText) {
|
|
62
|
+
if (typeof arrayOrText === 'string') {
|
|
63
|
+
return `<li>${arrayOrText}</li>`
|
|
64
|
+
}
|
|
65
|
+
if (Array.isArray(arrayOrText)) {
|
|
66
|
+
let resultListText = '<ul>'
|
|
67
|
+
for (const item of arrayOrText) {
|
|
68
|
+
if (Array.isArray(item)) {
|
|
69
|
+
resultListText += `<li>${arrayToList(item)}</li>`
|
|
70
|
+
} else {
|
|
71
|
+
resultListText += `<li>${item}</li>`
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
resultListText += '</ul>'
|
|
75
|
+
arrayOrText = resultListText
|
|
76
|
+
}
|
|
77
|
+
return arrayOrText
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function renderIndex(pages, nodate = 'nodate', headingTag = 'h3') {
|
|
81
|
+
if (!pages) {
|
|
82
|
+
pages = readIndex()
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const renderList = {}
|
|
86
|
+
for (const page of pages) {
|
|
87
|
+
if (page.index) {
|
|
88
|
+
const url = config.relative_path ? config.relative_path + page.url : page.url
|
|
89
|
+
if (page.published === '1970-01-01') {
|
|
90
|
+
if (!renderList[nodate]) {
|
|
91
|
+
renderList[nodate] = []
|
|
92
|
+
}
|
|
93
|
+
renderList[nodate].push(`<a href="${url}">${page.title}</a>`)
|
|
94
|
+
continue
|
|
95
|
+
}
|
|
96
|
+
const published = new Date(page.published)
|
|
97
|
+
const year = `${published.getFullYear()}年`
|
|
98
|
+
const date = `${published.getMonth() +1}月${published.getDate()}日`
|
|
99
|
+
if (!renderList[year]) {
|
|
100
|
+
renderList[year] = []
|
|
101
|
+
}
|
|
102
|
+
renderList[year].push(`<a href="${url}">${page.title}</a> (${date})`)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const resultText = []
|
|
107
|
+
for (const key in renderList) {
|
|
108
|
+
resultText.push(`<${headingTag}>${key}</${headingTag}>`)
|
|
109
|
+
if (Array.isArray(renderList[key])) {
|
|
110
|
+
resultText.push(arrayToList(renderList[key]))
|
|
111
|
+
} else {
|
|
112
|
+
resultText.push(`<p>${renderList[key]}</p>`)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return resultText.join('\n')
|
|
116
|
+
}
|
|
2
117
|
|
|
3
118
|
export function additionalHelper() {
|
|
4
119
|
return 'これは追加ヘルパーによって出力されているメッセージです。'
|
package/src-sample/js/editor.js
CHANGED
|
@@ -102,7 +102,13 @@ const sidebarToggle = (e) => {
|
|
|
102
102
|
toggle.addEventListener('click', (e) => {
|
|
103
103
|
e.preventDefault()
|
|
104
104
|
main.classList.toggle('sidebar-close')
|
|
105
|
+
localStorage.setItem('sidebar-is-open', !main.classList.contains('sidebar-close'))
|
|
105
106
|
})
|
|
107
|
+
if (localStorage.getItem('sidebar-is-open') === 'true') {
|
|
108
|
+
main.classList.remove('sidebar-close')
|
|
109
|
+
} else {
|
|
110
|
+
main.classList.add('sidebar-close')
|
|
111
|
+
}
|
|
106
112
|
const hamburger = document.querySelector('.hamburger-menu input[type="checkbox"]')
|
|
107
113
|
hamburger.addEventListener('change', (e) => {
|
|
108
114
|
main.classList.toggle('sidebar-close')
|
package/src-sample/js/error.js
CHANGED
|
@@ -4,22 +4,12 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>{{SITE_NAME}}</title>
|
|
7
|
-
{
|
|
8
|
-
<link rel="stylesheet" href="${/css/editor.css<<editor.css}">
|
|
7
|
+
<link rel="stylesheet" href="${/css/editor.css<<reset.css,editor.css}">
|
|
9
8
|
<script src="/js/editor.js" defer></script>
|
|
10
9
|
|
|
11
10
|
</head>
|
|
12
11
|
<body>
|
|
13
|
-
<
|
|
14
|
-
<p class="container">
|
|
15
|
-
<a href="/">{{SITE_NAME}}/Editor</a>
|
|
16
|
-
</p>
|
|
17
|
-
<div class="hamburger-menu">
|
|
18
|
-
<input type="checkbox" id="menu-btn-check">
|
|
19
|
-
<label for="menu-btn-check" class="menu-btn"><span></span></label>
|
|
20
|
-
</div>
|
|
21
|
-
</header>
|
|
22
|
-
<main class="container sidebar-close">
|
|
12
|
+
<main class="container">
|
|
23
13
|
<div class="sidebar">
|
|
24
14
|
<ul>
|
|
25
15
|
<script type="ssg">
|
|
@@ -31,15 +21,24 @@
|
|
|
31
21
|
<div class="sidebar-toggle"> </div>
|
|
32
22
|
</div>
|
|
33
23
|
<form action="/editor" class="editor" method="post" id="editor">
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
24
|
+
<div class="editor-options">
|
|
25
|
+
<div>
|
|
26
|
+
<input id="inputFileName" name="inputFileName" type="text" value="" placeholder="sample.md">
|
|
27
|
+
<select id="selectDataFile" name="selectDataFile">
|
|
28
|
+
<option value="">新規作成</option>
|
|
29
|
+
<script type="ssg">
|
|
30
|
+
return helper.readIndex().map(p => {
|
|
39
31
|
return `<option value="${p.name}.${p.__filetype}">${p.url}.${p.__filetype}</option>`
|
|
40
32
|
}).join("\n")
|
|
41
|
-
|
|
42
|
-
|
|
33
|
+
</script>
|
|
34
|
+
</select>
|
|
35
|
+
</div>
|
|
36
|
+
<div>
|
|
37
|
+
<input type="submit" value="preview" data-url="/preview">
|
|
38
|
+
<input type="submit" value="save" data-url="/editor">
|
|
39
|
+
<a href="/">戻る</a>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
43
42
|
<div class="textareaAndPreview">
|
|
44
43
|
<textarea id="editorTextArea" name="content" cols="30" rows="10">
|
|
45
44
|
{{ MARKDOWN_NOT_PARSED }}
|
|
@@ -49,12 +48,11 @@
|
|
|
49
48
|
</div>
|
|
50
49
|
</div>
|
|
51
50
|
<input type="hidden" name="token" value="{{TOKEN}}">
|
|
52
|
-
<div>
|
|
53
|
-
<input type="submit" value="preview" data-url="/preview">
|
|
54
|
-
<input type="submit" value="save" data-url="/editor">
|
|
55
|
-
<a href="/">戻る</a>
|
|
56
|
-
</div>
|
|
57
51
|
</form>
|
|
52
|
+
<div class="hamburger-menu">
|
|
53
|
+
<input type="checkbox" id="menu-btn-check">
|
|
54
|
+
<label for="menu-btn-check" class="menu-btn"><span></span></label>
|
|
55
|
+
</div>
|
|
58
56
|
</main>
|
|
59
57
|
</body>
|
|
60
58
|
</html>
|
package/helper/index.js
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { allData } from "../lib/indexer.js";
|
|
2
|
-
import { replaceVariablesFilter } from "../lib/filter.js";
|
|
3
|
-
import config from '../lib/config.js'
|
|
4
|
-
|
|
5
|
-
export function readIndex (filter = null) {
|
|
6
|
-
const data = Object.entries(allData)
|
|
7
|
-
.sort((a, b) => new Date(b[1].published) - new Date(a[1].published))
|
|
8
|
-
return filter
|
|
9
|
-
? data.filter(v => v[0].indexOf(filter) === 0).map(v => v[1])
|
|
10
|
-
: data.map(v => v[1])
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function dateFormat(dateString) {
|
|
14
|
-
const date = new Date(dateString)
|
|
15
|
-
return `${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日`
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function render(text, variables) {
|
|
19
|
-
return replaceVariablesFilter(text, variables)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function getPageData(name) {
|
|
23
|
-
return allData[name]
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
let indexedItemsSorted = null
|
|
27
|
-
export function indexedItems() {
|
|
28
|
-
if (indexedItemsSorted) {
|
|
29
|
-
return indexedItemsSorted
|
|
30
|
-
}
|
|
31
|
-
const sorted = readIndex()
|
|
32
|
-
.filter(v => v.index && v.published != '1970-01-01')
|
|
33
|
-
.sort((a, b) => new Date(a.published) - new Date(b.published))
|
|
34
|
-
let prev, next
|
|
35
|
-
for (const item of sorted) {
|
|
36
|
-
if (prev) {
|
|
37
|
-
prev.next = {
|
|
38
|
-
name: item.name,
|
|
39
|
-
published: item.published,
|
|
40
|
-
url: item.url,
|
|
41
|
-
title: item.title,
|
|
42
|
-
}
|
|
43
|
-
item.prev = {
|
|
44
|
-
name: prev.name,
|
|
45
|
-
published: prev.published,
|
|
46
|
-
url: prev.url,
|
|
47
|
-
title: prev.title,
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
prev = item
|
|
51
|
-
}
|
|
52
|
-
indexedItemsSorted = sorted
|
|
53
|
-
return indexedItemsSorted
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* 配列を再帰的に順不同リストに変換する
|
|
58
|
-
* @param {Array|string} arrayOrText
|
|
59
|
-
* @returns {mixed}
|
|
60
|
-
*/
|
|
61
|
-
export function arrayToList(arrayOrText) {
|
|
62
|
-
if (typeof arrayOrText === 'string') {
|
|
63
|
-
return `<li>${arrayOrText}</li>`
|
|
64
|
-
}
|
|
65
|
-
if (Array.isArray(arrayOrText)) {
|
|
66
|
-
let resultListText = '<ul>'
|
|
67
|
-
for (const item of arrayOrText) {
|
|
68
|
-
if (Array.isArray(item)) {
|
|
69
|
-
resultListText += `<li>${arrayToList(item)}</li>`
|
|
70
|
-
} else {
|
|
71
|
-
resultListText += `<li>${item}</li>`
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
resultListText += '</ul>'
|
|
75
|
-
arrayOrText = resultListText
|
|
76
|
-
}
|
|
77
|
-
return arrayOrText
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export function renderIndex(pages, nodate = 'nodate', headingTag = 'h3') {
|
|
81
|
-
if (!pages) {
|
|
82
|
-
pages = readIndex()
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const renderList = {}
|
|
86
|
-
for (const page of pages) {
|
|
87
|
-
if (page.index) {
|
|
88
|
-
const url = config.relative_path ? config.relative_path + page.url : page.url
|
|
89
|
-
if (page.published === '1970-01-01') {
|
|
90
|
-
if (!renderList[nodate]) {
|
|
91
|
-
renderList[nodate] = []
|
|
92
|
-
}
|
|
93
|
-
renderList[nodate].push(`<a href="${url}">${page.title}</a>`)
|
|
94
|
-
continue
|
|
95
|
-
}
|
|
96
|
-
const published = new Date(page.published)
|
|
97
|
-
const year = `${published.getFullYear()}年`
|
|
98
|
-
const date = `${published.getMonth() +1}月${published.getDate()}日`
|
|
99
|
-
if (!renderList[year]) {
|
|
100
|
-
renderList[year] = []
|
|
101
|
-
}
|
|
102
|
-
renderList[year].push(`<a href="${url}">${page.title}</a> (${date})`)
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const resultText = []
|
|
107
|
-
for (const key in renderList) {
|
|
108
|
-
resultText.push(`<${headingTag}>${key}</${headingTag}>`)
|
|
109
|
-
if (Array.isArray(renderList[key])) {
|
|
110
|
-
resultText.push(arrayToList(renderList[key]))
|
|
111
|
-
} else {
|
|
112
|
-
resultText.push(`<p>${renderList[key]}</p>`)
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return resultText.join('\n')
|
|
116
|
-
}
|