@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
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
## Visão geral
|
|
2
|
+
|
|
3
|
+
Blocos de exemplos de código renderizam SFCs Vue do projeto como previews ao vivo dentro das páginas Markdown.
|
|
4
|
+
|
|
5
|
+
Eles são úteis quando a documentação precisa mostrar o comportamento real de um componente e ainda permitir que leitores inspecionem o código fonte exato por trás do preview.
|
|
6
|
+
|
|
7
|
+
O bloco é escrito com o elemento Markdown customizado `<d-block-code-example>`.
|
|
8
|
+
|
|
9
|
+
## Arquivos de exemplo
|
|
10
|
+
|
|
11
|
+
Coloque os componentes de exemplo em `src/examples/**/*.vue` no projeto que usa o Docsector.
|
|
12
|
+
|
|
13
|
+
O Docsector descobre esses arquivos durante o build com Vite. O valor de `src` é normalizado para kebab-case, então este bloco:
|
|
14
|
+
|
|
15
|
+
```html
|
|
16
|
+
<d-block-code-example src="manual/code-examples/basic-counter" title="Basic counter" />
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
resolve este arquivo:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
src/examples/manual/code-examples/BasicCounter.vue
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Também é possível usar `file` no lugar de `src` ao migrar exemplos inspirados nos padrões do Quasar Docs.
|
|
26
|
+
|
|
27
|
+
## Atributos
|
|
28
|
+
|
|
29
|
+
| Atributo | Finalidade |
|
|
30
|
+
|----------|------------|
|
|
31
|
+
| `src` | Id do exemplo dentro de `src/examples/**/*.vue` |
|
|
32
|
+
| `file` | Alias de `src` |
|
|
33
|
+
| `title` | Título exibido acima do preview |
|
|
34
|
+
| `expanded` | Abre o painel de fonte por padrão quando definido como `true` |
|
|
35
|
+
| `codepen` | Mostra a ação do CodePen, exceto quando definido como `false` |
|
|
36
|
+
| `scrollable` | Dá ao preview uma altura fixa com rolagem |
|
|
37
|
+
| `overflow` | Permite overflow horizontal e vertical no preview |
|
|
38
|
+
| `height` | Define uma altura customizada para o preview, como `360` ou `420px` |
|
|
39
|
+
|
|
40
|
+
## Painel de fonte
|
|
41
|
+
|
|
42
|
+
O botão de fonte abre o SFC Vue dividido em abas Template, Script, Style e All quando essas seções existem.
|
|
43
|
+
|
|
44
|
+
O painel reutiliza o renderizador padrão de blocos de código do Docsector, então leitores recebem syntax highlighting, suporte a cópia e o mesmo tratamento visual em temas claro e escuro.
|
|
45
|
+
|
|
46
|
+
## Link de fonte no GitHub
|
|
47
|
+
|
|
48
|
+
O botão do GitHub abre o SFC do exemplo no repositório do projeto quando o Docsector consegue derivar a URL a partir de `github.editBaseUrl` ou `links.github` em `docsector.config.js`.
|
|
49
|
+
|
|
50
|
+
## Exportação para CodePen
|
|
51
|
+
|
|
52
|
+
O botão do CodePen fica disponível quando o código pode ser transformado com segurança para uma demo somente no navegador.
|
|
53
|
+
|
|
54
|
+
A primeira implementação suporta SFCs Vue simples com template, style opcional e script Options API com `export default`. Imports nomeados de `vue` e `quasar` são convertidos para globais do navegador. Exemplos que usam `<script setup>`, scripts TypeScript ou imports locais continuam renderizando no Docsector, mas a ação do CodePen fica desativada.
|
|
55
|
+
|
|
56
|
+
Use `codepen="false"` quando um exemplo intencionalmente não deve ser exportado.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
## Showcase
|
|
2
|
+
|
|
3
|
+
### Basic Counter
|
|
4
|
+
|
|
5
|
+
This example is rendered from a real Vue SFC under `src/examples/manual/code-examples/BasicCounter.vue`.
|
|
6
|
+
|
|
7
|
+
<d-block-code-example src="manual/code-examples/basic-counter" title="Basic counter">
|
|
8
|
+
Use the source button to inspect the SFC sections, or open the compatible demo in CodePen.
|
|
9
|
+
</d-block-code-example>
|
|
10
|
+
|
|
11
|
+
### Expanded Source by Default
|
|
12
|
+
|
|
13
|
+
Use `expanded="true"` when the source code is part of the lesson and should be visible as soon as the reader reaches the example.
|
|
14
|
+
|
|
15
|
+
<d-block-code-example src="manual/code-examples/inline-notice" title="Expanded source example" expanded="true">
|
|
16
|
+
This example intentionally starts with the source panel open.
|
|
17
|
+
</d-block-code-example>
|
|
18
|
+
|
|
19
|
+
## Authoring Syntax
|
|
20
|
+
|
|
21
|
+
```html
|
|
22
|
+
<d-block-code-example src="manual/code-examples/basic-counter" title="Basic counter">
|
|
23
|
+
Optional caption rendered as inline Markdown.
|
|
24
|
+
</d-block-code-example>
|
|
25
|
+
|
|
26
|
+
<d-block-code-example src="manual/code-examples/inline-notice" title="Expanded source example" expanded="true">
|
|
27
|
+
The source panel starts open.
|
|
28
|
+
</d-block-code-example>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Features Visible Above
|
|
32
|
+
|
|
33
|
+
- **Live preview** rendered from the bundled Vue component
|
|
34
|
+
- **Source toggle** with Template, Script, Style, and All tabs
|
|
35
|
+
- **CodePen action** for compatible examples
|
|
36
|
+
- **GitHub action** pointing to the example SFC
|
|
37
|
+
- **Expanded source state** with `expanded="true"`
|
|
38
|
+
- **Inline Markdown caption** below the preview
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
## Showcase
|
|
2
|
+
|
|
3
|
+
### Contador básico
|
|
4
|
+
|
|
5
|
+
Este exemplo é renderizado a partir de um SFC Vue real em `src/examples/manual/code-examples/BasicCounter.vue`.
|
|
6
|
+
|
|
7
|
+
<d-block-code-example src="manual/code-examples/basic-counter" title="Basic counter">
|
|
8
|
+
Use o botão de fonte para inspecionar as seções do SFC, ou abra a demo compatível no CodePen.
|
|
9
|
+
</d-block-code-example>
|
|
10
|
+
|
|
11
|
+
### Fonte expandida por padrão
|
|
12
|
+
|
|
13
|
+
Use `expanded="true"` quando o código fonte faz parte da explicação e deve aparecer assim que o leitor chegar ao exemplo.
|
|
14
|
+
|
|
15
|
+
<d-block-code-example src="manual/code-examples/inline-notice" title="Expanded source example" expanded="true">
|
|
16
|
+
Este exemplo intencionalmente começa com o painel de fonte aberto.
|
|
17
|
+
</d-block-code-example>
|
|
18
|
+
|
|
19
|
+
## Sintaxe de autoria
|
|
20
|
+
|
|
21
|
+
```html
|
|
22
|
+
<d-block-code-example src="manual/code-examples/basic-counter" title="Basic counter">
|
|
23
|
+
Legenda opcional renderizada como Markdown inline.
|
|
24
|
+
</d-block-code-example>
|
|
25
|
+
|
|
26
|
+
<d-block-code-example src="manual/code-examples/inline-notice" title="Expanded source example" expanded="true">
|
|
27
|
+
O painel de fonte começa aberto.
|
|
28
|
+
</d-block-code-example>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Recursos visíveis acima
|
|
32
|
+
|
|
33
|
+
- **Preview ao vivo** renderizado a partir do componente Vue empacotado
|
|
34
|
+
- **Alternância de fonte** com abas Template, Script, Style e All
|
|
35
|
+
- **Ação do CodePen** para exemplos compatíveis
|
|
36
|
+
- **Ação do GitHub** apontando para o SFC do exemplo
|
|
37
|
+
- **Estado de fonte expandida** com `expanded="true"`
|
|
38
|
+
- **Legenda em Markdown inline** abaixo do preview
|
|
@@ -514,6 +514,34 @@ export default {
|
|
|
514
514
|
}
|
|
515
515
|
},
|
|
516
516
|
|
|
517
|
+
'/content/blocks/code-examples': {
|
|
518
|
+
config: {
|
|
519
|
+
icon: 'integration_instructions',
|
|
520
|
+
status: 'new',
|
|
521
|
+
meta: {
|
|
522
|
+
description: {
|
|
523
|
+
'en-US': 'Code examples — Documentation of Docsector Reader',
|
|
524
|
+
'pt-BR': 'Exemplos de código — Documentacao do Docsector Reader'
|
|
525
|
+
}
|
|
526
|
+
},
|
|
527
|
+
book: 'manual',
|
|
528
|
+
menu: {},
|
|
529
|
+
subpages: {
|
|
530
|
+
showcase: true
|
|
531
|
+
}
|
|
532
|
+
},
|
|
533
|
+
data: {
|
|
534
|
+
'en-US': { title: 'Code examples' },
|
|
535
|
+
'pt-BR': { title: 'Exemplos de código' }
|
|
536
|
+
},
|
|
537
|
+
metadata: {
|
|
538
|
+
tags: {
|
|
539
|
+
'en-US': 'code examples live preview vue sfc source codepen component demo',
|
|
540
|
+
'pt-BR': 'exemplos código preview ao vivo vue sfc fonte codepen componente demo'
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
},
|
|
544
|
+
|
|
517
545
|
'/content/blocks/mermaid-diagrams': {
|
|
518
546
|
config: {
|
|
519
547
|
icon: 'account_tree',
|
package/src/quasar.factory.js
CHANGED
|
@@ -1144,6 +1144,82 @@ function createBooksPlugin (projectRoot) {
|
|
|
1144
1144
|
}
|
|
1145
1145
|
}
|
|
1146
1146
|
|
|
1147
|
+
function buildVirtualCodeExamplesModule () {
|
|
1148
|
+
return `const componentModules = import.meta.glob('/src/examples/**/*.vue')
|
|
1149
|
+
const sourceModules = import.meta.glob('/src/examples/**/*.vue', { query: '?raw', import: 'default' })
|
|
1150
|
+
|
|
1151
|
+
const trimSlashes = (value) => String(value || '').replace(/\\\\/g, '/').replace(/^\\/+|\\/+$/g, '')
|
|
1152
|
+
const toKebabSegment = (value) => String(value || '')
|
|
1153
|
+
.replace(/\\.vue$/i, '')
|
|
1154
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
1155
|
+
.replace(/[\\s_]+/g, '-')
|
|
1156
|
+
.replace(/-+/g, '-')
|
|
1157
|
+
.toLowerCase()
|
|
1158
|
+
|
|
1159
|
+
export const normalizeCodeExampleId = (value) => trimSlashes(value)
|
|
1160
|
+
.replace(/^src\\/examples\\//i, '')
|
|
1161
|
+
.replace(/^examples\\//i, '')
|
|
1162
|
+
.replace(/\\.vue$/i, '')
|
|
1163
|
+
.split('/')
|
|
1164
|
+
.filter(Boolean)
|
|
1165
|
+
.map(toKebabSegment)
|
|
1166
|
+
.join('/')
|
|
1167
|
+
|
|
1168
|
+
export const codeExamples = Object.keys(componentModules).reduce((examples, filePath) => {
|
|
1169
|
+
const id = normalizeCodeExampleId(filePath)
|
|
1170
|
+
|
|
1171
|
+
examples[id] = {
|
|
1172
|
+
id,
|
|
1173
|
+
filePath,
|
|
1174
|
+
loadComponent: componentModules[filePath],
|
|
1175
|
+
loadSource: sourceModules[filePath]
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
return examples
|
|
1179
|
+
}, {})
|
|
1180
|
+
|
|
1181
|
+
export const codeExampleIds = Object.keys(codeExamples).sort()
|
|
1182
|
+
|
|
1183
|
+
export const resolveCodeExample = (value) => {
|
|
1184
|
+
const id = normalizeCodeExampleId(value)
|
|
1185
|
+
const entry = codeExamples[id]
|
|
1186
|
+
|
|
1187
|
+
if (!entry) {
|
|
1188
|
+
return {
|
|
1189
|
+
id,
|
|
1190
|
+
filePath: '',
|
|
1191
|
+
exists: false,
|
|
1192
|
+
loadComponent: null,
|
|
1193
|
+
loadSource: null
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
return {
|
|
1198
|
+
...entry,
|
|
1199
|
+
exists: true
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
export default codeExamples
|
|
1204
|
+
`
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
function createCodeExamplesPlugin () {
|
|
1208
|
+
const virtualId = 'virtual:docsector-code-examples'
|
|
1209
|
+
const resolvedId = '\0' + virtualId
|
|
1210
|
+
|
|
1211
|
+
return {
|
|
1212
|
+
name: 'docsector-code-examples',
|
|
1213
|
+
resolveId (id) {
|
|
1214
|
+
if (id === virtualId) return resolvedId
|
|
1215
|
+
},
|
|
1216
|
+
load (id) {
|
|
1217
|
+
if (id !== resolvedId) return null
|
|
1218
|
+
return buildVirtualCodeExamplesModule()
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1147
1223
|
/**
|
|
1148
1224
|
* Create the HJSON Vite plugin for loading .hjson files as ES modules.
|
|
1149
1225
|
*/
|
|
@@ -2919,6 +2995,7 @@ export function createQuasarConfig (options = {}) {
|
|
|
2919
2995
|
|
|
2920
2996
|
vitePlugins: [
|
|
2921
2997
|
createBooksPlugin(projectRoot),
|
|
2998
|
+
createCodeExamplesPlugin(),
|
|
2922
2999
|
createHjsonPlugin(),
|
|
2923
3000
|
createHomePageOverridePlugin(projectRoot),
|
|
2924
3001
|
createGitDatesPlugin(projectRoot),
|
package/src/store/Page.js
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
const getNodePath = (nodes, targetId, ancestry = []) => {
|
|
2
|
+
for (const node of nodes) {
|
|
3
|
+
const nextAncestry = [...ancestry, node.id]
|
|
4
|
+
|
|
5
|
+
if (node.id === targetId) {
|
|
6
|
+
return nextAncestry
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
if (Array.isArray(node.children) && node.children.length > 0) {
|
|
10
|
+
const childPath = getNodePath(node.children, targetId, nextAncestry)
|
|
11
|
+
|
|
12
|
+
if (childPath !== null) {
|
|
13
|
+
return childPath
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return null
|
|
19
|
+
}
|
|
20
|
+
|
|
1
21
|
export default {
|
|
2
22
|
namespaced: true,
|
|
3
23
|
|
|
@@ -82,8 +102,12 @@ export default {
|
|
|
82
102
|
state.nodesExpanded = [0]
|
|
83
103
|
},
|
|
84
104
|
pushNodesExpanded (state, nodeId) {
|
|
85
|
-
|
|
86
|
-
|
|
105
|
+
const nodePath = getNodePath(state.nodes, nodeId) || [nodeId]
|
|
106
|
+
|
|
107
|
+
for (const pathNodeId of nodePath) {
|
|
108
|
+
if (!state.nodesExpanded.includes(pathNodeId)) {
|
|
109
|
+
state.nodesExpanded.push(pathNodeId)
|
|
110
|
+
}
|
|
87
111
|
}
|
|
88
112
|
},
|
|
89
113
|
|