@tenjuu99/blog 0.2.7 → 0.2.9

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 CHANGED
@@ -89,7 +89,7 @@ blog.json を開いて、 `site_name` を変更します。
89
89
  "src_dir": "src",
90
90
  "dist_dir": "dist",
91
91
  "distribute_raw": "image",
92
- "helper": "helper/index.js"
92
+ "helper": "index.js"
93
93
  }
94
94
  ```
95
95
 
package/bin/dev-server CHANGED
@@ -50,6 +50,7 @@ const proceed = () => {
50
50
  })
51
51
  child.on('exit', (code, signal) => {
52
52
  console.error(`process exit: ${code}, SIGNAL: ${signal}`);
53
+ child.kill('SIGINT')
53
54
  })
54
55
 
55
56
  return child
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": "helper/index.js",
18
+ "helper": "index.js",
28
19
  "editor_enable": true
29
20
  }' > "$(pwd)/blog.json"
30
21
  echo "create blog.json"
package/lib/filter.js CHANGED
@@ -1,7 +1,4 @@
1
1
  import helper from '../lib/helper.js'
2
- import { srcDir } from './dir.js'
3
- import config from './config.js'
4
- import replaceVariablesFilter from './replaceVariablesFilter.js'
5
2
 
6
3
  /**
7
4
  * @param {string} condition
@@ -84,30 +81,6 @@ const replaceIfFilter = (text, variables) => {
84
81
  return text
85
82
  }
86
83
 
87
- /**
88
- * 配列を再帰的に順不同リストに変換する
89
- * @param {Array|string} arrayOrText
90
- * @returns {mixed}
91
- */
92
- const arrayToList = (arrayOrText) => {
93
- if (typeof arrayOrText === 'string') {
94
- return `<li>${arrayOrText}</li>`
95
- }
96
- if (Array.isArray(arrayOrText)) {
97
- let resultListText = '<ul>'
98
- for (const item of arrayOrText) {
99
- if (Array.isArray(item)) {
100
- resultListText += `<li>${arrayToList(item)}</li>`
101
- } else {
102
- resultListText += `<li>${item}</li>`
103
- }
104
- }
105
- resultListText += '</ul>'
106
- arrayOrText = resultListText
107
- }
108
- return arrayOrText
109
- }
110
-
111
84
  const replaceScriptFilter = async (text, variables) => {
112
85
  let replaced = text
113
86
  const scriptRegexp = new RegExp(/({script}|\<script\s.*type="ssg".*>)(?<script>[\s\S]*?)(\{\/script}|\<\/script>)/g)
@@ -127,9 +100,6 @@ const replaceScriptFilter = async (text, variables) => {
127
100
  case 'null':
128
101
  result = ''
129
102
  }
130
- if (Array.isArray(result)) {
131
- result = helper.arrayToList(result)
132
- }
133
103
  replaced = replaced.replace(script.replace, result)
134
104
  }
135
105
  return replaced
@@ -137,6 +107,5 @@ const replaceScriptFilter = async (text, variables) => {
137
107
 
138
108
  export {
139
109
  replaceIfFilter,
140
- replaceScriptFilter,
141
- replaceVariablesFilter
110
+ replaceScriptFilter
142
111
  }
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 { srcDir } from './dir.js'
2
+ import { helperDir } from './dir.js'
4
3
 
5
- let helper = {...helperDefault}
4
+ let helper = {}
6
5
 
7
- if (config['helper']) {
8
- const helperAdditional = await import(`${srcDir}/${config.helper}`)
9
- helper = Object.assign(helper, helperAdditional)
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/render.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  replaceIfFilter,
3
- replaceScriptFilter,
4
- replaceVariablesFilter
3
+ replaceScriptFilter
5
4
  } from './filter.js'
5
+ import replaceVariablesFilter from './replaceVariablesFilter.js'
6
6
  import includeFilter from './includeFilter.js'
7
7
  import { marked } from "marked";
8
8
  import { applyTemplate } from './applyTemplate.js'
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@tenjuu99/blog",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "blog template",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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: 10px 0;
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: 15px 20px;
35
+ padding: 5px;
32
36
  justify-content:center;
33
37
  height: 100%;
34
38
  /* width: 100%; */
35
- margin: 0 auto;
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
- transition: flex-basis 0.3s;
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: rgba(104, 117, 154);
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 0 0 20px;
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: #fff;
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
- background: rgba(104, 117, 154);
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: #ffffff;
226
+ background-color: #666666;
212
227
  position: absolute;
213
228
  transition: transform 0.3s, background-color 0.3s;
214
229
  }
@@ -0,0 +1,3 @@
1
+ export function additionalHelper() {
2
+ return 'これは追加ヘルパーによって出力されているメッセージです。'
3
+ }
@@ -1,7 +1,118 @@
1
1
  import { allData } from '@tenjuu99/blog/lib/indexer.js'
2
+ import replaceVariablesFilter from '@tenjuu99/blog/lib/replaceVariablesFilter.js'
3
+ import config from '@tenjuu99/blog/lib/config.js'
2
4
 
3
- export function additionalHelper() {
4
- return 'これは追加ヘルパーによって出力されているメッセージです。'
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')
5
116
  }
6
117
 
7
118
  export function isEditorEnabled() {
@@ -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')
@@ -4,4 +4,5 @@ const url = new URL(location)
4
4
  if (url.pathname !== '/editor') {
5
5
  const link = document.querySelector('.editor_link')
6
6
  link.href = `/editor?md=${url.pathname.replace('/', '')}.md`
7
+ link.innerHTML = `${url.pathname.replace('/', '')}のページを作成する`
7
8
  }
@@ -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
- {include('template/css.html')}
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
- <header>
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">&nbsp;</div>
32
22
  </div>
33
23
  <form action="/editor" class="editor" method="post" id="editor">
34
- <input id="inputFileName" name="inputFileName" type="text" value="" placeholder="sample.md">
35
- <select id="selectDataFile" name="selectDataFile">
36
- <option value="">新規作成</option>
37
- <script type="ssg">
38
- return helper.readIndex().map(p => {
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
- </script>
42
- </select>
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
- }