slidev-theme-gtlabo 1.0.4 → 1.0.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/components/CitationListPage.vue +107 -109
- package/components/Header.vue +27 -11
- package/layouts/cover.vue +11 -3
- package/package.json +1 -1
|
@@ -7,23 +7,23 @@
|
|
|
7
7
|
/>
|
|
8
8
|
|
|
9
9
|
<!-- 参考文献リスト -->
|
|
10
|
-
<div class="flex-1 overflow-y-auto px-
|
|
10
|
+
<div class="flex-1 overflow-y-auto px-6 py-2">
|
|
11
11
|
<div
|
|
12
12
|
v-if="citationsList.length > 0"
|
|
13
|
-
class="space-y-
|
|
13
|
+
class="space-y-3"
|
|
14
14
|
>
|
|
15
15
|
<div
|
|
16
16
|
v-for="(citation, index) in citationsList"
|
|
17
17
|
:key="citation.key"
|
|
18
|
-
class="citation-item border-l-
|
|
18
|
+
class="citation-item border-l-2 border-sky-400 pl-3 py-1"
|
|
19
19
|
>
|
|
20
20
|
<!-- 引用キー -->
|
|
21
|
-
<div class="text-
|
|
21
|
+
<div class="text-sm font-semibold text-sky-700 mb-1">
|
|
22
22
|
[{{ citation.key }}]
|
|
23
23
|
</div>
|
|
24
24
|
|
|
25
25
|
<!-- 引用情報 -->
|
|
26
|
-
<div class="text-gray-
|
|
26
|
+
<div class="text-xs text-gray-700 leading-relaxed">
|
|
27
27
|
<!-- 著者 -->
|
|
28
28
|
<span
|
|
29
29
|
v-if="citation.data.author"
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
<!-- DOI -->
|
|
88
88
|
<div
|
|
89
89
|
v-if="citation.data.doi"
|
|
90
|
-
class="mt-
|
|
90
|
+
class="mt-1 text-xs text-blue-600"
|
|
91
91
|
>
|
|
92
92
|
DOI: <a
|
|
93
93
|
:href="`https://doi.org/${citation.data.doi}`"
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
<!-- URL -->
|
|
102
102
|
<div
|
|
103
103
|
v-if="citation.data.url && !citation.data.doi"
|
|
104
|
-
class="mt-
|
|
104
|
+
class="mt-1 text-xs text-blue-600"
|
|
105
105
|
>
|
|
106
106
|
URL: <a
|
|
107
107
|
:href="citation.data.url"
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
<!-- ISSN -->
|
|
116
116
|
<div
|
|
117
117
|
v-if="citation.data.issn"
|
|
118
|
-
class="mt-1 text-
|
|
118
|
+
class="mt-1 text-xs text-gray-500"
|
|
119
119
|
>
|
|
120
120
|
ISSN: {{ citation.data.issn }}
|
|
121
121
|
</div>
|
|
@@ -126,124 +126,122 @@
|
|
|
126
126
|
<!-- 参考文献がない場合 -->
|
|
127
127
|
<div
|
|
128
128
|
v-else
|
|
129
|
-
class="text-center text-gray-500 mt-
|
|
129
|
+
class="text-center text-gray-500 mt-12"
|
|
130
130
|
>
|
|
131
|
-
<div class="text-
|
|
131
|
+
<div class="text-lg">
|
|
132
132
|
参考文献が設定されていません
|
|
133
133
|
</div>
|
|
134
|
-
<div class="text-
|
|
135
|
-
frontmatterの<code class="bg-gray-200 px-
|
|
134
|
+
<div class="text-xs mt-2">
|
|
135
|
+
frontmatterの<code class="bg-gray-200 px-1 py-0.5 rounded text-xs">citations</code>セクションに参考文献を追加してください
|
|
136
136
|
</div>
|
|
137
137
|
</div>
|
|
138
138
|
</div>
|
|
139
139
|
|
|
140
140
|
<!-- フッター(必要に応じて) -->
|
|
141
|
-
<div class="flex-shrink-0 mt-
|
|
142
|
-
<div class="text-
|
|
141
|
+
<div class="flex-shrink-0 mt-4 pt-2 border-t border-gray-300 px-6">
|
|
142
|
+
<div class="text-xs text-gray-600 text-center">
|
|
143
143
|
{{ citationsList.length }} 件の参考文献
|
|
144
144
|
</div>
|
|
145
145
|
</div>
|
|
146
146
|
</div>
|
|
147
147
|
</template>
|
|
148
148
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
//
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
type: String,
|
|
169
|
-
default: 'key', // 'key', 'author', 'year' など
|
|
170
|
-
}
|
|
171
|
-
})
|
|
172
|
-
|
|
173
|
-
// 参考文献リストを生成
|
|
174
|
-
const citationsList = computed(() => {
|
|
175
|
-
if (!citations || typeof citations !== 'object') {
|
|
176
|
-
return []
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const list = Object.keys(citations).map(key => ({
|
|
180
|
-
key,
|
|
181
|
-
data: citations[key]
|
|
182
|
-
}))
|
|
183
|
-
|
|
184
|
-
// ソート処理
|
|
185
|
-
switch (props.sortBy) {
|
|
186
|
-
case 'author':
|
|
187
|
-
return list.sort((a, b) => {
|
|
188
|
-
const authorA = a.data.author || ''
|
|
189
|
-
const authorB = b.data.author || ''
|
|
190
|
-
return authorA.localeCompare(authorB)
|
|
191
|
-
})
|
|
192
|
-
case 'year':
|
|
193
|
-
return list.sort((a, b) => {
|
|
194
|
-
const yearA = parseInt(a.data.year) || 0
|
|
195
|
-
const yearB = parseInt(b.data.year) || 0
|
|
196
|
-
return yearB - yearA // 降順(新しい順)
|
|
197
|
-
})
|
|
198
|
-
case 'key':
|
|
199
|
-
default:
|
|
200
|
-
return list.sort((a, b) => a.key.localeCompare(b.key))
|
|
201
|
-
}
|
|
202
|
-
})
|
|
203
|
-
|
|
204
|
-
// スタイル別のフォーマット関数(将来的な拡張用)
|
|
205
|
-
const formatCitation = (citation, style = 'academic') => {
|
|
206
|
-
// 現在は academic スタイルのみ実装
|
|
207
|
-
// 将来的にIEEE、APA等のスタイルを追加可能
|
|
208
|
-
return citation
|
|
149
|
+
<script setup>
|
|
150
|
+
import { computed } from 'vue'
|
|
151
|
+
import { useSlideContext } from '@slidev/client'
|
|
152
|
+
|
|
153
|
+
// Slidevコンテキストからconfigsにアクセス
|
|
154
|
+
const { $slidev } = useSlideContext()
|
|
155
|
+
const citations = $slidev.configs.citations || {}
|
|
156
|
+
|
|
157
|
+
// プロパティ定義(必要に応じて)
|
|
158
|
+
const props = defineProps({
|
|
159
|
+
// 表示スタイルのカスタマイズ用
|
|
160
|
+
style: {
|
|
161
|
+
type: String,
|
|
162
|
+
default: 'academic', // 'academic', 'ieee', 'apa' など
|
|
163
|
+
},
|
|
164
|
+
// 表示順序
|
|
165
|
+
sortBy: {
|
|
166
|
+
type: String,
|
|
167
|
+
default: 'key', // 'key', 'author', 'year' など
|
|
209
168
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
.citation-item:hover {
|
|
218
|
-
background-color: rgba(14, 165, 233, 0.05);
|
|
219
|
-
border-left-width: 6px;
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
// 参考文献リストを生成
|
|
172
|
+
const citationsList = computed(() => {
|
|
173
|
+
if (!citations || typeof citations !== 'object') {
|
|
174
|
+
return []
|
|
220
175
|
}
|
|
221
176
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
177
|
+
const list = Object.keys(citations).map(key => ({
|
|
178
|
+
key,
|
|
179
|
+
data: citations[key]
|
|
180
|
+
}))
|
|
227
181
|
|
|
228
|
-
|
|
229
|
-
|
|
182
|
+
// ソート処理
|
|
183
|
+
switch (props.sortBy) {
|
|
184
|
+
case 'author':
|
|
185
|
+
return list.sort((a, b) => {
|
|
186
|
+
const authorA = a.data.author || ''
|
|
187
|
+
const authorB = b.data.author || ''
|
|
188
|
+
return authorA.localeCompare(authorB)
|
|
189
|
+
})
|
|
190
|
+
case 'year':
|
|
191
|
+
return list.sort((a, b) => {
|
|
192
|
+
const yearA = parseInt(a.data.year) || 0
|
|
193
|
+
const yearB = parseInt(b.data.year) || 0
|
|
194
|
+
return yearB - yearA // 降順(新しい順)
|
|
195
|
+
})
|
|
196
|
+
case 'key':
|
|
197
|
+
default:
|
|
198
|
+
return list.sort((a, b) => a.key.localeCompare(b.key))
|
|
230
199
|
}
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
// スタイル別のフォーマット関数(将来的な拡張用)
|
|
203
|
+
const formatCitation = (citation, style = 'academic') => {
|
|
204
|
+
// 現在は academic スタイルのみ実装
|
|
205
|
+
// 将来的にIEEE、APA等のスタイルを追加可能
|
|
206
|
+
return citation
|
|
207
|
+
}
|
|
208
|
+
</script>
|
|
231
209
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
210
|
+
<style scoped>
|
|
211
|
+
.citation-item {
|
|
212
|
+
transition: all 0.2s ease-in-out;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.citation-item:hover {
|
|
216
|
+
background-color: rgba(14, 165, 233, 0.05);
|
|
217
|
+
border-left-width: 3px;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/* スクロールバーのスタイリング */
|
|
221
|
+
.overflow-y-auto {
|
|
222
|
+
scrollbar-width: thin;
|
|
223
|
+
scrollbar-color: rgba(14, 165, 233, 0.3) transparent;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.overflow-y-auto::-webkit-scrollbar {
|
|
227
|
+
width: 4px;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.overflow-y-auto::-webkit-scrollbar-track {
|
|
231
|
+
background: transparent;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.overflow-y-auto::-webkit-scrollbar-thumb {
|
|
235
|
+
background-color: rgba(14, 165, 233, 0.3);
|
|
236
|
+
border-radius: 2px;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.overflow-y-auto::-webkit-scrollbar-thumb:hover {
|
|
240
|
+
background-color: rgba(14, 165, 233, 0.5);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/* コードブロックのスタイル */
|
|
244
|
+
code {
|
|
245
|
+
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
246
|
+
}
|
|
247
|
+
</style>
|
package/components/Header.vue
CHANGED
|
@@ -204,7 +204,7 @@ const displayChapterList = computed(() => {
|
|
|
204
204
|
}
|
|
205
205
|
})
|
|
206
206
|
|
|
207
|
-
// appendix
|
|
207
|
+
// appendixの開始ページを計算(SectionDivider考慮版)
|
|
208
208
|
const appendixStartPage = computed(() => {
|
|
209
209
|
const totalPages = $slidev.nav.total
|
|
210
210
|
const appendixChapters = chapterList.value.filter(chapter => chapter.isAppendix)
|
|
@@ -225,32 +225,48 @@ const appendixStartPage = computed(() => {
|
|
|
225
225
|
return total + sectionCount
|
|
226
226
|
}, 0)
|
|
227
227
|
|
|
228
|
+
// appendix用SectionDividerの数
|
|
229
|
+
const appendixDividerCount = appendixChapters.length
|
|
230
|
+
|
|
228
231
|
console.log(' appendixSectionCount:', appendixSectionCount)
|
|
229
|
-
|
|
232
|
+
console.log(' appendixDividerCount:', appendixDividerCount)
|
|
233
|
+
|
|
234
|
+
// 全ページ数からappendixのセクション数とSectionDivider数を引いて開始位置を計算
|
|
235
|
+
const result = totalPages - appendixSectionCount - appendixDividerCount + 1
|
|
230
236
|
console.log(' appendixあり - 結果:', result)
|
|
231
237
|
return result
|
|
232
238
|
})
|
|
233
239
|
|
|
234
|
-
//
|
|
240
|
+
// 調整されたページ総数(SectionDivider考慮版)
|
|
235
241
|
const adjustedTotal = computed(() => {
|
|
236
242
|
// chapterList(全体)からappendixを検索
|
|
237
243
|
const appendixChapters = chapterList.value.filter(chapter => chapter.isAppendix)
|
|
244
|
+
const normalChapters = chapterList.value.filter(chapter => !chapter.isAppendix && chapter.key !== 'ref')
|
|
245
|
+
|
|
246
|
+
// SectionDividerの数を計算
|
|
247
|
+
const normalChapterDividers = normalChapters.length // 通常章のSectionDivider数
|
|
248
|
+
const appendixChapterDividers = appendixChapters.length // appendix章のSectionDivider数
|
|
249
|
+
const totalDividers = normalChapterDividers + appendixChapterDividers
|
|
238
250
|
|
|
239
251
|
// デバッグ用ログ
|
|
240
252
|
console.log('全chapterList:', chapterList.value)
|
|
253
|
+
console.log('normalChapters:', normalChapters)
|
|
241
254
|
console.log('appendixChapters:', appendixChapters)
|
|
242
|
-
console.log('
|
|
255
|
+
console.log('normalChapterDividers:', normalChapterDividers)
|
|
256
|
+
console.log('appendixChapterDividers:', appendixChapterDividers)
|
|
257
|
+
console.log('totalDividers:', totalDividers)
|
|
243
258
|
console.log('$slidev.nav.total:', $slidev.nav.total)
|
|
244
|
-
console.log('appendixStartPage.value:', appendixStartPage.value)
|
|
245
259
|
|
|
246
260
|
if (appendixChapters.length === 0) {
|
|
247
|
-
// appendix
|
|
248
|
-
|
|
249
|
-
|
|
261
|
+
// appendixがない場合は全体のページ数から表紙と
|
|
262
|
+
const result = $slidev.nav.total - 1
|
|
263
|
+
console.log('appendixなし - 計算結果:', result)
|
|
264
|
+
return result
|
|
250
265
|
} else {
|
|
251
|
-
// appendixがある場合はappendix
|
|
252
|
-
|
|
253
|
-
|
|
266
|
+
// appendixがある場合はappendix開始前のページ数から表紙と通常章のSectionDividerを除く
|
|
267
|
+
const result = appendixStartPage.value - 2
|
|
268
|
+
console.log('appendixあり - 計算結果:', result)
|
|
269
|
+
return result
|
|
254
270
|
}
|
|
255
271
|
})
|
|
256
272
|
|
package/layouts/cover.vue
CHANGED
|
@@ -45,9 +45,17 @@
|
|
|
45
45
|
getTitleSizeClass($slidev.configs.titleSize || 'large')
|
|
46
46
|
]"
|
|
47
47
|
>
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
<template v-if="Array.isArray($slidev.configs.coverTitle)">
|
|
49
|
+
<span v-for="(line, index) in $slidev.configs.coverTitle" :key="index">
|
|
50
|
+
{{ line }}
|
|
51
|
+
<br v-if="index < $slidev.configs.coverTitle.length - 1">
|
|
52
|
+
</span>
|
|
53
|
+
</template>
|
|
54
|
+
<template v-else>
|
|
55
|
+
{{ $slidev.configs.coverTitle.first }}
|
|
56
|
+
<br>
|
|
57
|
+
{{ $slidev.configs.coverTitle.second }}
|
|
58
|
+
</template>
|
|
51
59
|
</div>
|
|
52
60
|
|
|
53
61
|
<!-- 著者情報 -->
|