@docsector/docsector-reader 4.0.1 โ 4.1.0
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 +17 -0
- package/bin/docsector.js +1 -1
- package/package.json +1 -1
- package/src/components/DBlockCodeExample.vue +423 -0
- package/src/components/DBlockSourceCode.vue +1 -7
- package/src/components/DPageTokens.vue +14 -0
- package/src/components/code-block-highlighting.js +16 -0
- package/src/components/code-example-source.js +363 -0
- package/src/components/page-section-tokens.js +89 -1
- package/src/examples/manual/code-examples/BasicCounter.vue +63 -0
- package/src/examples/manual/code-examples/InlineNotice.vue +60 -0
- package/src/pages/manual/content/blocks/code-examples.overview.en-US.md +56 -0
- package/src/pages/manual/content/blocks/code-examples.overview.pt-BR.md +56 -0
- package/src/pages/manual/content/blocks/code-examples.showcase.en-US.md +38 -0
- package/src/pages/manual/content/blocks/code-examples.showcase.pt-BR.md +38 -0
- package/src/pages/manual.index.js +28 -0
- package/src/quasar.factory.js +77 -0
- package/src/store/Page.js +26 -2
package/README.md
CHANGED
|
@@ -79,6 +79,7 @@ Transform Markdown content into beautiful, navigable documentation sites โ wit
|
|
|
79
79
|
- ๐๏ธ **Multi-Version History** โ Archive older major versions under `src/pages/.old/<version>/` and expose them at prefixed routes (e.g. `/v0.x/guide/...`) while keeping the current docs at unprefixed routes
|
|
80
80
|
- ๐ท๏ธ **Version Selector Badges** โ Every version in the sidebar selector displays a color-coded badge: green for released, orange for draft, red for deprecated; fully customizable via `badge: { label, color, textColor }`
|
|
81
81
|
- ๐ **Tabbed Code Blocks** โ Group consecutive fenced code blocks into tabs using the `group` and `tab` attributes in the fence info line
|
|
82
|
+
- ๐งช **Live Code Example Blocks** โ Use `<d-block-code-example src="..." />` to render bundled Vue SFC examples with a live preview, GitHub source link, source toggle, and CodePen export for compatible examples
|
|
82
83
|
- ๐ **Breadcrumb Path Display** โ Show a file path breadcrumb above code blocks with the `breadcrumb` attribute; renders as clickable path segments
|
|
83
84
|
- ๐จ **File Type Icons** โ Automatically resolves file extension or filename to a Material Icon Theme SVG icon, shown inline in tabs and beside the last breadcrumb segment
|
|
84
85
|
- โ๏ธ **Single Config File** โ Customize branding, links, and languages via `docsector.config.js`
|
|
@@ -1023,6 +1024,22 @@ Notes:
|
|
|
1023
1024
|
Supported alert types: `NOTE`, `TIP`, `IMPORTANT`, `WARNING`, `CAUTION`.
|
|
1024
1025
|
Regular blockquotes without `[!TYPE]` continue to work normally.
|
|
1025
1026
|
|
|
1027
|
+
### Code Example Blocks
|
|
1028
|
+
|
|
1029
|
+
```html
|
|
1030
|
+
<d-block-code-example src="manual/code-examples/basic-counter" title="Basic counter">
|
|
1031
|
+
Optional caption rendered as inline Markdown.
|
|
1032
|
+
</d-block-code-example>
|
|
1033
|
+
```
|
|
1034
|
+
|
|
1035
|
+
Notes:
|
|
1036
|
+
|
|
1037
|
+
- Store live examples as Vue SFCs under `src/examples/**/*.vue`; for example, `src="manual/code-examples/basic-counter"` resolves `src/examples/manual/code-examples/BasicCounter.vue` after kebab-case normalization.
|
|
1038
|
+
- Readers get a live preview, a GitHub button for the example SFC, a source button with Template / Script / Style / All tabs, and a CodePen button when the example can be exported safely.
|
|
1039
|
+
- Use `expanded="true"` only when the source code should be visible by default.
|
|
1040
|
+
- CodePen export currently supports plain Vue SFCs with a template, optional style, and an Options API `export default` script. Named imports from `vue` and `quasar` are converted to browser globals.
|
|
1041
|
+
- Examples using `<script setup>`, TypeScript scripts, or local imports still render in Docsector, but the CodePen action is disabled. Use `codepen="false"` to hide it intentionally.
|
|
1042
|
+
|
|
1026
1043
|
### File Attachment Blocks
|
|
1027
1044
|
|
|
1028
1045
|
```html
|
package/bin/docsector.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docsector/docsector-reader",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "A documentation rendering engine built with Vue 3, Quasar v2 and Vite. Transform Markdown into beautiful, navigable documentation sites.",
|
|
5
5
|
"productName": "Docsector Reader",
|
|
6
6
|
"author": "Rodrigo de Araujo Vieira",
|
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, markRaw, ref, watch } from 'vue'
|
|
3
|
+
import { openURL, Quasar, useQuasar } from 'quasar'
|
|
4
|
+
|
|
5
|
+
import { resolveCodeExample } from 'virtual:docsector-code-examples'
|
|
6
|
+
import docsectorConfig from 'docsector.config.js'
|
|
7
|
+
|
|
8
|
+
import DBlockSourceCode from './DBlockSourceCode.vue'
|
|
9
|
+
import {
|
|
10
|
+
canCreateCodepenPayload,
|
|
11
|
+
createCodeExampleGitHubUrl,
|
|
12
|
+
createCodeExampleTabs,
|
|
13
|
+
createCodepenPayload,
|
|
14
|
+
getCodepenUnsupportedReason
|
|
15
|
+
} from './code-example-source'
|
|
16
|
+
|
|
17
|
+
defineOptions({
|
|
18
|
+
name: 'DBlockCodeExample'
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
const props = defineProps({
|
|
22
|
+
index: {
|
|
23
|
+
type: Number,
|
|
24
|
+
required: true
|
|
25
|
+
},
|
|
26
|
+
src: {
|
|
27
|
+
type: String,
|
|
28
|
+
default: ''
|
|
29
|
+
},
|
|
30
|
+
title: {
|
|
31
|
+
type: String,
|
|
32
|
+
default: ''
|
|
33
|
+
},
|
|
34
|
+
caption: {
|
|
35
|
+
type: String,
|
|
36
|
+
default: ''
|
|
37
|
+
},
|
|
38
|
+
expanded: {
|
|
39
|
+
type: Boolean,
|
|
40
|
+
default: false
|
|
41
|
+
},
|
|
42
|
+
codepen: {
|
|
43
|
+
type: Boolean,
|
|
44
|
+
default: true
|
|
45
|
+
},
|
|
46
|
+
scrollable: {
|
|
47
|
+
type: Boolean,
|
|
48
|
+
default: false
|
|
49
|
+
},
|
|
50
|
+
overflow: {
|
|
51
|
+
type: Boolean,
|
|
52
|
+
default: false
|
|
53
|
+
},
|
|
54
|
+
height: {
|
|
55
|
+
type: String,
|
|
56
|
+
default: ''
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
const $q = useQuasar()
|
|
61
|
+
|
|
62
|
+
const isBusy = ref(false)
|
|
63
|
+
const errorMessage = ref('')
|
|
64
|
+
const component = ref(null)
|
|
65
|
+
const sourceText = ref('')
|
|
66
|
+
const sourceTabs = ref([])
|
|
67
|
+
const sourceOpen = ref(props.expanded)
|
|
68
|
+
const exampleFilePath = ref('')
|
|
69
|
+
let requestIndex = 0
|
|
70
|
+
|
|
71
|
+
const displayTitle = computed(() => props.title || props.src || 'Code example')
|
|
72
|
+
const frameTone = computed(() => $q.dark.isActive ? 'dark' : 'light')
|
|
73
|
+
const hasSource = computed(() => sourceText.value.trim().length > 0)
|
|
74
|
+
const codepenUnsupportedReason = computed(() => {
|
|
75
|
+
if (!hasSource.value) {
|
|
76
|
+
return 'Source code is still loading.'
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return getCodepenUnsupportedReason(sourceText.value)
|
|
80
|
+
})
|
|
81
|
+
const canOpenCodepen = computed(() => props.codepen && hasSource.value && canCreateCodepenPayload(sourceText.value))
|
|
82
|
+
const codepenTooltip = computed(() => canOpenCodepen.value ? 'Edit in CodePen' : codepenUnsupportedReason.value)
|
|
83
|
+
const githubUrl = computed(() => createCodeExampleGitHubUrl(exampleFilePath.value, docsectorConfig))
|
|
84
|
+
const canOpenGitHub = computed(() => githubUrl.value !== '')
|
|
85
|
+
const previewStyle = computed(() => {
|
|
86
|
+
const style = {}
|
|
87
|
+
const normalizedHeight = normalizeCssLength(props.height)
|
|
88
|
+
|
|
89
|
+
if (normalizedHeight) {
|
|
90
|
+
style.height = normalizedHeight
|
|
91
|
+
} else if (props.scrollable) {
|
|
92
|
+
style.height = '500px'
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return style
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
watch(() => props.expanded, (value) => {
|
|
99
|
+
sourceOpen.value = value
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
watch(() => props.src, () => {
|
|
103
|
+
loadExample()
|
|
104
|
+
}, { immediate: true })
|
|
105
|
+
|
|
106
|
+
function normalizeCssLength (value = '') {
|
|
107
|
+
const normalized = String(value || '').trim()
|
|
108
|
+
|
|
109
|
+
if (!normalized) {
|
|
110
|
+
return ''
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (/^-?\d+(?:\.\d+)?$/.test(normalized)) {
|
|
114
|
+
return `${normalized}px`
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return normalized
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async function loadExample () {
|
|
121
|
+
const currentRequest = ++requestIndex
|
|
122
|
+
const resolved = resolveCodeExample(props.src)
|
|
123
|
+
|
|
124
|
+
isBusy.value = true
|
|
125
|
+
errorMessage.value = ''
|
|
126
|
+
component.value = null
|
|
127
|
+
sourceText.value = ''
|
|
128
|
+
sourceTabs.value = []
|
|
129
|
+
exampleFilePath.value = ''
|
|
130
|
+
|
|
131
|
+
if (!props.src) {
|
|
132
|
+
errorMessage.value = 'Code example source is missing.'
|
|
133
|
+
isBusy.value = false
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (!resolved.exists || typeof resolved.loadComponent !== 'function' || typeof resolved.loadSource !== 'function') {
|
|
138
|
+
errorMessage.value = `Code example not found: ${resolved.id || props.src}`
|
|
139
|
+
isBusy.value = false
|
|
140
|
+
return
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
const [componentModule, rawSource] = await Promise.all([
|
|
145
|
+
resolved.loadComponent(),
|
|
146
|
+
resolved.loadSource()
|
|
147
|
+
])
|
|
148
|
+
|
|
149
|
+
if (currentRequest !== requestIndex) {
|
|
150
|
+
return
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
component.value = markRaw(componentModule.default || componentModule)
|
|
154
|
+
sourceText.value = String(rawSource || '')
|
|
155
|
+
sourceTabs.value = createCodeExampleTabs(sourceText.value)
|
|
156
|
+
exampleFilePath.value = resolved.filePath || ''
|
|
157
|
+
} catch (err) {
|
|
158
|
+
if (currentRequest !== requestIndex) {
|
|
159
|
+
return
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
errorMessage.value = err?.message || `Unable to load code example: ${props.src}`
|
|
163
|
+
} finally {
|
|
164
|
+
if (currentRequest === requestIndex) {
|
|
165
|
+
isBusy.value = false
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function toggleSource () {
|
|
171
|
+
sourceOpen.value = !sourceOpen.value
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function submitCodepenPayload (payload) {
|
|
175
|
+
if (typeof document === 'undefined') {
|
|
176
|
+
return
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const form = document.createElement('form')
|
|
180
|
+
const input = document.createElement('input')
|
|
181
|
+
|
|
182
|
+
form.method = 'post'
|
|
183
|
+
form.action = 'https://codepen.io/pen/define/'
|
|
184
|
+
form.target = '_blank'
|
|
185
|
+
form.rel = 'noopener'
|
|
186
|
+
form.style.display = 'none'
|
|
187
|
+
|
|
188
|
+
input.type = 'hidden'
|
|
189
|
+
input.name = 'data'
|
|
190
|
+
input.value = JSON.stringify(payload)
|
|
191
|
+
|
|
192
|
+
form.appendChild(input)
|
|
193
|
+
document.body.appendChild(form)
|
|
194
|
+
form.submit()
|
|
195
|
+
form.remove()
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function openCodepen () {
|
|
199
|
+
if (!canOpenCodepen.value) {
|
|
200
|
+
return
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const sourceUrl = typeof window === 'undefined'
|
|
204
|
+
? ''
|
|
205
|
+
: `${window.location.origin}${window.location.pathname}${window.location.hash}`
|
|
206
|
+
|
|
207
|
+
submitCodepenPayload(createCodepenPayload(sourceText.value, {
|
|
208
|
+
title: displayTitle.value,
|
|
209
|
+
quasarVersion: Quasar.version,
|
|
210
|
+
sourceUrl
|
|
211
|
+
}))
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function openGitHub () {
|
|
215
|
+
if (canOpenGitHub.value) {
|
|
216
|
+
openURL(githubUrl.value)
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
</script>
|
|
220
|
+
|
|
221
|
+
<template>
|
|
222
|
+
<div
|
|
223
|
+
class="d-block-code-example"
|
|
224
|
+
:class="`d-block-code-example--${frameTone}`"
|
|
225
|
+
>
|
|
226
|
+
<div class="d-block-code-example__toolbar">
|
|
227
|
+
<div class="d-block-code-example__title">{{ displayTitle }}</div>
|
|
228
|
+
|
|
229
|
+
<q-space />
|
|
230
|
+
|
|
231
|
+
<q-btn
|
|
232
|
+
class="d-block-code-example__button"
|
|
233
|
+
dense
|
|
234
|
+
flat
|
|
235
|
+
round
|
|
236
|
+
icon="fab fa-github"
|
|
237
|
+
:disable="!canOpenGitHub"
|
|
238
|
+
aria-label="View example on GitHub"
|
|
239
|
+
@click="openGitHub"
|
|
240
|
+
>
|
|
241
|
+
<q-tooltip>{{ canOpenGitHub ? 'View on GitHub' : 'GitHub source is unavailable' }}</q-tooltip>
|
|
242
|
+
</q-btn>
|
|
243
|
+
|
|
244
|
+
<q-btn
|
|
245
|
+
v-if="codepen"
|
|
246
|
+
class="d-block-code-example__button"
|
|
247
|
+
dense
|
|
248
|
+
flat
|
|
249
|
+
round
|
|
250
|
+
icon="fab fa-codepen"
|
|
251
|
+
:disable="!canOpenCodepen"
|
|
252
|
+
aria-label="Edit in CodePen"
|
|
253
|
+
@click="openCodepen"
|
|
254
|
+
>
|
|
255
|
+
<q-tooltip>{{ codepenTooltip }}</q-tooltip>
|
|
256
|
+
</q-btn>
|
|
257
|
+
|
|
258
|
+
<q-btn
|
|
259
|
+
class="d-block-code-example__button"
|
|
260
|
+
dense
|
|
261
|
+
flat
|
|
262
|
+
round
|
|
263
|
+
icon="code"
|
|
264
|
+
:disable="!hasSource"
|
|
265
|
+
:aria-label="sourceOpen ? 'Hide source' : 'View source'"
|
|
266
|
+
@click="toggleSource"
|
|
267
|
+
>
|
|
268
|
+
<q-tooltip>{{ sourceOpen ? 'Hide source' : 'View source' }}</q-tooltip>
|
|
269
|
+
</q-btn>
|
|
270
|
+
</div>
|
|
271
|
+
|
|
272
|
+
<q-slide-transition>
|
|
273
|
+
<div
|
|
274
|
+
v-show="sourceOpen && hasSource"
|
|
275
|
+
class="d-block-code-example__source"
|
|
276
|
+
>
|
|
277
|
+
<d-block-source-code
|
|
278
|
+
:index="index"
|
|
279
|
+
language="vue"
|
|
280
|
+
:text="sourceText"
|
|
281
|
+
:tabs="sourceTabs"
|
|
282
|
+
/>
|
|
283
|
+
</div>
|
|
284
|
+
</q-slide-transition>
|
|
285
|
+
|
|
286
|
+
<q-linear-progress
|
|
287
|
+
v-if="isBusy"
|
|
288
|
+
color="primary"
|
|
289
|
+
indeterminate
|
|
290
|
+
/>
|
|
291
|
+
|
|
292
|
+
<div
|
|
293
|
+
class="d-block-code-example__preview"
|
|
294
|
+
:class="{
|
|
295
|
+
'd-block-code-example__preview--scrollable': scrollable,
|
|
296
|
+
'd-block-code-example__preview--overflow': overflow
|
|
297
|
+
}"
|
|
298
|
+
:style="previewStyle"
|
|
299
|
+
>
|
|
300
|
+
<component
|
|
301
|
+
v-if="component && !errorMessage"
|
|
302
|
+
:is="component"
|
|
303
|
+
class="d-block-code-example__component"
|
|
304
|
+
/>
|
|
305
|
+
|
|
306
|
+
<div
|
|
307
|
+
v-else-if="errorMessage"
|
|
308
|
+
class="d-block-code-example__fallback"
|
|
309
|
+
>
|
|
310
|
+
<q-icon
|
|
311
|
+
name="warning"
|
|
312
|
+
size="22px"
|
|
313
|
+
/>
|
|
314
|
+
<span>{{ errorMessage }}</span>
|
|
315
|
+
</div>
|
|
316
|
+
</div>
|
|
317
|
+
|
|
318
|
+
<div
|
|
319
|
+
v-if="caption"
|
|
320
|
+
class="d-block-code-example__caption"
|
|
321
|
+
v-html="caption"
|
|
322
|
+
></div>
|
|
323
|
+
</div>
|
|
324
|
+
</template>
|
|
325
|
+
|
|
326
|
+
<style lang="sass">
|
|
327
|
+
body.body--light
|
|
328
|
+
--d-code-example-bg: #ffffff
|
|
329
|
+
--d-code-example-border: rgba(37, 67, 45, 0.16)
|
|
330
|
+
--d-code-example-toolbar-bg: #f6f8f5
|
|
331
|
+
--d-code-example-toolbar-text: #26352b
|
|
332
|
+
--d-code-example-preview-bg: #ffffff
|
|
333
|
+
--d-code-example-caption: #405148
|
|
334
|
+
--d-code-example-muted: #5d7563
|
|
335
|
+
|
|
336
|
+
body.body--dark
|
|
337
|
+
--d-code-example-bg: #111512
|
|
338
|
+
--d-code-example-border: rgba(197, 220, 200, 0.18)
|
|
339
|
+
--d-code-example-toolbar-bg: #1a211c
|
|
340
|
+
--d-code-example-toolbar-text: #e8efe9
|
|
341
|
+
--d-code-example-preview-bg: #0c0f0d
|
|
342
|
+
--d-code-example-caption: #c7d4ca
|
|
343
|
+
--d-code-example-muted: #9aafa0
|
|
344
|
+
|
|
345
|
+
.d-block-code-example
|
|
346
|
+
background: var(--d-code-example-bg)
|
|
347
|
+
border: 1px solid var(--d-code-example-border)
|
|
348
|
+
border-radius: 6px
|
|
349
|
+
box-shadow: 0 1px 1px rgb(0 0 0 / 8%)
|
|
350
|
+
margin: 18px 0
|
|
351
|
+
max-width: calc(100vw - 40px)
|
|
352
|
+
overflow: hidden
|
|
353
|
+
|
|
354
|
+
&__toolbar
|
|
355
|
+
align-items: center
|
|
356
|
+
background: var(--d-code-example-toolbar-bg)
|
|
357
|
+
color: var(--d-code-example-toolbar-text)
|
|
358
|
+
display: flex
|
|
359
|
+
gap: 4px
|
|
360
|
+
min-height: 42px
|
|
361
|
+
min-width: 0
|
|
362
|
+
padding: 4px 8px 4px 14px
|
|
363
|
+
|
|
364
|
+
&__title
|
|
365
|
+
font-size: 14px
|
|
366
|
+
font-weight: 600
|
|
367
|
+
line-height: 20px
|
|
368
|
+
min-width: 0
|
|
369
|
+
overflow: hidden
|
|
370
|
+
text-overflow: ellipsis
|
|
371
|
+
white-space: nowrap
|
|
372
|
+
|
|
373
|
+
&__button
|
|
374
|
+
color: var(--d-code-example-muted)
|
|
375
|
+
flex: 0 0 auto
|
|
376
|
+
|
|
377
|
+
&__source
|
|
378
|
+
border-top: 1px solid var(--d-code-example-border)
|
|
379
|
+
|
|
380
|
+
.source-code
|
|
381
|
+
box-shadow: none
|
|
382
|
+
margin: 0
|
|
383
|
+
max-width: 100%
|
|
384
|
+
|
|
385
|
+
.source-code-frame
|
|
386
|
+
border: 0
|
|
387
|
+
border-radius: 0
|
|
388
|
+
|
|
389
|
+
&__preview
|
|
390
|
+
background: var(--d-code-example-preview-bg)
|
|
391
|
+
min-height: 96px
|
|
392
|
+
min-width: 0
|
|
393
|
+
overflow: hidden
|
|
394
|
+
position: relative
|
|
395
|
+
|
|
396
|
+
&--scrollable
|
|
397
|
+
overflow-y: auto
|
|
398
|
+
|
|
399
|
+
&--overflow
|
|
400
|
+
overflow: auto
|
|
401
|
+
|
|
402
|
+
&__component
|
|
403
|
+
display: block
|
|
404
|
+
min-width: 0
|
|
405
|
+
|
|
406
|
+
&__fallback
|
|
407
|
+
align-items: center
|
|
408
|
+
color: var(--d-code-example-muted)
|
|
409
|
+
display: flex
|
|
410
|
+
gap: 8px
|
|
411
|
+
min-height: 96px
|
|
412
|
+
padding: 18px
|
|
413
|
+
|
|
414
|
+
&__caption
|
|
415
|
+
border-top: 1px solid var(--d-code-example-border)
|
|
416
|
+
color: var(--d-code-example-caption)
|
|
417
|
+
font-size: 14px
|
|
418
|
+
line-height: 1.55
|
|
419
|
+
padding: 10px 14px 12px
|
|
420
|
+
|
|
421
|
+
p
|
|
422
|
+
margin: 0
|
|
423
|
+
</style>
|
|
@@ -2,13 +2,7 @@
|
|
|
2
2
|
import { ref, computed, watch } from 'vue'
|
|
3
3
|
import { useQuasar } from 'quasar'
|
|
4
4
|
import { useStore } from 'vuex'
|
|
5
|
-
import Prism from '
|
|
6
|
-
// @ Load Prism languages
|
|
7
|
-
import 'prismjs/components/prism-markup-templating' // dependency for prism-php extension
|
|
8
|
-
// PHP
|
|
9
|
-
import 'prismjs/components/prism-php'
|
|
10
|
-
// Bash
|
|
11
|
-
import 'prismjs/components/prism-bash'
|
|
5
|
+
import Prism from './code-block-highlighting'
|
|
12
6
|
import { looksLikeFileName, resolveFileIconUrl } from '../composables/useFileIcon'
|
|
13
7
|
|
|
14
8
|
defineOptions({
|
|
@@ -34,6 +34,7 @@ import DBlockQuickLinks from './DBlockQuickLinks.vue'
|
|
|
34
34
|
import DBlockTimeline from './DBlockTimeline.vue'
|
|
35
35
|
import DBlockExpandable from './DBlockExpandable.vue'
|
|
36
36
|
import DBlockStepper from './DBlockStepper.vue'
|
|
37
|
+
import DBlockCodeExample from './DBlockCodeExample.vue'
|
|
37
38
|
</script>
|
|
38
39
|
|
|
39
40
|
<template>
|
|
@@ -135,6 +136,19 @@ import DBlockStepper from './DBlockStepper.vue'
|
|
|
135
136
|
:tabs="token.tabs"
|
|
136
137
|
/>
|
|
137
138
|
|
|
139
|
+
<d-block-code-example
|
|
140
|
+
v-else-if="token.tag === 'code-example'"
|
|
141
|
+
:index="id + token.codeIndex"
|
|
142
|
+
:src="token.src"
|
|
143
|
+
:title="token.title"
|
|
144
|
+
:caption="token.caption"
|
|
145
|
+
:expanded="token.expanded"
|
|
146
|
+
:codepen="token.codepen"
|
|
147
|
+
:scrollable="token.scrollable"
|
|
148
|
+
:overflow="token.overflow"
|
|
149
|
+
:height="token.height"
|
|
150
|
+
/>
|
|
151
|
+
|
|
138
152
|
<d-block-mermaid-diagram
|
|
139
153
|
v-else-if="token.tag === 'mermaid'"
|
|
140
154
|
:content="token.content"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import Prism from 'prismjs'
|
|
2
|
+
|
|
3
|
+
import 'prismjs/components/prism-markup'
|
|
4
|
+
import 'prismjs/components/prism-markup-templating'
|
|
5
|
+
import 'prismjs/components/prism-javascript'
|
|
6
|
+
import 'prismjs/components/prism-css'
|
|
7
|
+
import 'prismjs/components/prism-php'
|
|
8
|
+
import 'prismjs/components/prism-bash'
|
|
9
|
+
|
|
10
|
+
if (!Prism.languages.vue && Prism.languages.markup?.tag?.addInlined) {
|
|
11
|
+
Prism.languages.markup.tag.addInlined('script', 'javascript')
|
|
12
|
+
Prism.languages.markup.tag.addInlined('style', 'css')
|
|
13
|
+
Prism.languages.vue = Prism.languages.markup
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default Prism
|