@docsector/docsector-reader 0.1.3 → 0.2.1
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 +175 -47
- package/bin/docsector.js +408 -17
- package/package.json +16 -9
- package/quasar.config.js +4 -111
- package/src/components/DH1.vue +1 -1
- package/src/components/DH2.vue +1 -1
- package/src/components/DH3.vue +1 -1
- package/src/components/DH4.vue +1 -1
- package/src/components/DH5.vue +1 -1
- package/src/components/DH6.vue +1 -1
- package/src/components/DMenu.vue +4 -4
- package/src/components/DPage.vue +3 -3
- package/src/components/DPageAnchor.vue +1 -1
- package/src/components/QZoom.js +1 -1
- package/src/components/QZoom.sass +43 -0
- package/src/i18n/helpers.js +160 -0
- package/src/i18n/index.js +4 -117
- package/src/layouts/DefaultLayout.vue +1 -1
- package/src/pages/guide/getting-started.overview.en-US.md +29 -11
- package/src/pages/guide/getting-started.overview.pt-BR.md +29 -11
- package/src/quasar.factory.js +249 -0
- package/src/components/QZoom.styl +0 -43
package/src/components/DH6.vue
CHANGED
package/src/components/DMenu.vue
CHANGED
|
@@ -4,7 +4,7 @@ import { useRoute, useRouter } from 'vue-router'
|
|
|
4
4
|
import { useQuasar, scroll, openURL } from 'quasar'
|
|
5
5
|
import { useI18n } from 'vue-i18n'
|
|
6
6
|
|
|
7
|
-
import tags from '
|
|
7
|
+
import tags from '@docsector/tags'
|
|
8
8
|
import DMenuItem from './DMenuItem.vue'
|
|
9
9
|
import docsectorConfig from 'docsector.config.js'
|
|
10
10
|
|
|
@@ -35,8 +35,8 @@ const searchTerm = (term) => {
|
|
|
35
35
|
const locale = $q.localStorage.getItem('setting.language')
|
|
36
36
|
founds.value = []
|
|
37
37
|
|
|
38
|
-
for (const [index,
|
|
39
|
-
searchTermIterate(
|
|
38
|
+
for (const [index, group] of items.value.entries()) {
|
|
39
|
+
searchTermIterate(group, term, locale)
|
|
40
40
|
}
|
|
41
41
|
} else {
|
|
42
42
|
founds.value = false
|
|
@@ -54,7 +54,7 @@ const searchTermIterate = (items, term, locale) => {
|
|
|
54
54
|
founds.value[path] = false
|
|
55
55
|
|
|
56
56
|
// @ search in i18n/tags.hjson
|
|
57
|
-
if (tags[locale] && tags[locale].length > 0) {
|
|
57
|
+
if (tags[locale] && Object.keys(tags[locale]).length > 0) {
|
|
58
58
|
founds.value[path] = tags[locale][path]?.indexOf(term) !== -1
|
|
59
59
|
if (founds.value[path] === false && locale !== 'en-US') {
|
|
60
60
|
founds.value[path] = tags['en-US'][path]?.indexOf(term) !== -1
|
package/src/components/DPage.vue
CHANGED
|
@@ -4,10 +4,10 @@ import { useStore } from 'vuex'
|
|
|
4
4
|
import { useRoute, useRouter } from 'vue-router'
|
|
5
5
|
import { useQuasar } from 'quasar'
|
|
6
6
|
|
|
7
|
-
import useNavigator from '
|
|
7
|
+
import useNavigator from '../composables/useNavigator'
|
|
8
8
|
|
|
9
|
-
import DPageAnchor from '
|
|
10
|
-
import DPageMeta from '
|
|
9
|
+
import DPageAnchor from './DPageAnchor.vue'
|
|
10
|
+
import DPageMeta from './DPageMeta.vue'
|
|
11
11
|
|
|
12
12
|
const store = useStore()
|
|
13
13
|
const router = useRouter()
|
|
@@ -4,7 +4,7 @@ import { useStore } from 'vuex'
|
|
|
4
4
|
import { useQuasar } from 'quasar'
|
|
5
5
|
import { useRoute } from "vue-router";
|
|
6
6
|
|
|
7
|
-
import useNavigator from '
|
|
7
|
+
import useNavigator from '../composables/useNavigator'
|
|
8
8
|
|
|
9
9
|
const store = useStore()
|
|
10
10
|
const $q = useQuasar()
|
package/src/components/QZoom.js
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
$box-shadow: 1px 1px 7px 1px rgba(0,0,0,.2) !default
|
|
2
|
+
|
|
3
|
+
.q-zoom
|
|
4
|
+
position: relative
|
|
5
|
+
padding: 0
|
|
6
|
+
margin: 0
|
|
7
|
+
|
|
8
|
+
&__zoom-in
|
|
9
|
+
cursor: zoom-in
|
|
10
|
+
|
|
11
|
+
&__zoom-out
|
|
12
|
+
cursor: zoom-out
|
|
13
|
+
|
|
14
|
+
&__overlay
|
|
15
|
+
position: fixed
|
|
16
|
+
transition: all .5s linear
|
|
17
|
+
left: 0
|
|
18
|
+
top: 0
|
|
19
|
+
width: 100%
|
|
20
|
+
height: 100%
|
|
21
|
+
background-color: transparent
|
|
22
|
+
padding: 0
|
|
23
|
+
margin: 0
|
|
24
|
+
z-index: 6000
|
|
25
|
+
|
|
26
|
+
&__content
|
|
27
|
+
position: relative
|
|
28
|
+
display: block
|
|
29
|
+
transition: all .5s cubic-bezier(.2,0,.2,1)
|
|
30
|
+
text-align: center
|
|
31
|
+
vertical-align: middle
|
|
32
|
+
width: 100%
|
|
33
|
+
height: 0
|
|
34
|
+
max-width: 100%
|
|
35
|
+
max-height: 100%
|
|
36
|
+
overflow: hidden
|
|
37
|
+
|
|
38
|
+
&__no-center
|
|
39
|
+
text-align: unset
|
|
40
|
+
vertical-align: unset
|
|
41
|
+
|
|
42
|
+
&__no-scroll
|
|
43
|
+
overflow: hidden
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docsector Reader — i18n Message Builder
|
|
3
|
+
*
|
|
4
|
+
* Extracts the markdown-to-i18n processing logic so consumer projects
|
|
5
|
+
* can call it with their own import.meta.glob results.
|
|
6
|
+
*
|
|
7
|
+
* Usage in consumer's src/i18n/index.js:
|
|
8
|
+
*
|
|
9
|
+
* import { buildMessages } from '@docsector/docsector-reader/i18n'
|
|
10
|
+
* import boot from 'pages/boot'
|
|
11
|
+
* import pages from 'pages'
|
|
12
|
+
*
|
|
13
|
+
* const langModules = import.meta.glob('./languages/*.hjson', { eager: true })
|
|
14
|
+
* const mdModules = import.meta.glob('../pages/**/*.md', { eager: true, query: '?raw', import: 'default' })
|
|
15
|
+
*
|
|
16
|
+
* export default buildMessages({ langModules, mdModules, pages, boot })
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Escape characters that conflict with vue-i18n message syntax.
|
|
21
|
+
*
|
|
22
|
+
* @param {string} source - Raw markdown string
|
|
23
|
+
* @returns {string} Escaped string safe for vue-i18n
|
|
24
|
+
*/
|
|
25
|
+
export function filter (source) {
|
|
26
|
+
const regex1 = /{/gm
|
|
27
|
+
const regex2 = /}/gm
|
|
28
|
+
const regex3 = /([@|])+/gm
|
|
29
|
+
|
|
30
|
+
source = source
|
|
31
|
+
.replace(regex1, '{')
|
|
32
|
+
.replace(regex2, '}')
|
|
33
|
+
.replace(regex3, "{'$&'}")
|
|
34
|
+
|
|
35
|
+
return source
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Build complete i18n messages from HJSON locale files and Markdown page content.
|
|
40
|
+
*
|
|
41
|
+
* @param {Object} options
|
|
42
|
+
* @param {Object} options.langModules - Result of import.meta.glob('./languages/*.hjson', { eager: true })
|
|
43
|
+
* @param {Object} options.mdModules - Result of import.meta.glob('../pages/**/*.md', { eager: true, query: '?raw', import: 'default' })
|
|
44
|
+
* @param {Object} options.pages - Page registry from pages/index.js
|
|
45
|
+
* @param {Object} options.boot - Boot meta from pages/boot.js
|
|
46
|
+
* @param {string[]} [options.langs] - Language codes to process (auto-detected from langModules if omitted)
|
|
47
|
+
* @returns {Object} Complete i18n messages object keyed by locale
|
|
48
|
+
*/
|
|
49
|
+
export function buildMessages ({ langModules, mdModules, pages, boot, langs }) {
|
|
50
|
+
// Auto-detect languages from HJSON files if not provided
|
|
51
|
+
if (!langs) {
|
|
52
|
+
langs = Object.keys(langModules).map(key => {
|
|
53
|
+
// key is like './languages/en-US.hjson' — extract 'en-US'
|
|
54
|
+
const match = key.match(/\/([^/]+)\.hjson$/)
|
|
55
|
+
return match ? match[1] : null
|
|
56
|
+
}).filter(Boolean)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const i18n = {}
|
|
60
|
+
|
|
61
|
+
function load (topPage, path, subpage, lang) {
|
|
62
|
+
const key = `../pages/${topPage}/${path}.${subpage}.${lang}.md`
|
|
63
|
+
const content = mdModules[key]
|
|
64
|
+
|
|
65
|
+
if (!content) {
|
|
66
|
+
console.warn(`[i18n] Missing markdown: ${key}`)
|
|
67
|
+
return ''
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const source = filter(typeof content === 'string' ? content : String(content))
|
|
71
|
+
return source
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// @ Iterate langs
|
|
75
|
+
for (const lang of langs) {
|
|
76
|
+
// Load HJSON language file
|
|
77
|
+
const langKey = `./languages/${lang}.hjson`
|
|
78
|
+
i18n[lang] = langModules[langKey]?.default || langModules[langKey] || {}
|
|
79
|
+
|
|
80
|
+
// @ Iterate pages
|
|
81
|
+
for (const [key, page] of Object.entries(pages)) {
|
|
82
|
+
const path = key.slice(1)
|
|
83
|
+
|
|
84
|
+
const config = page.config
|
|
85
|
+
const data = page.data
|
|
86
|
+
const meta = page.meta || boot.meta
|
|
87
|
+
|
|
88
|
+
const topPage = config?.type ?? 'manual'
|
|
89
|
+
|
|
90
|
+
// ---
|
|
91
|
+
|
|
92
|
+
const _ = path.split('/').reduce((accumulator, current) => {
|
|
93
|
+
let node = accumulator[current]
|
|
94
|
+
|
|
95
|
+
// Set object if not exists
|
|
96
|
+
if (node === undefined) {
|
|
97
|
+
accumulator[current] = {}
|
|
98
|
+
node = accumulator[current]
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// @ Set metadata
|
|
102
|
+
// title
|
|
103
|
+
if (node._ === undefined) {
|
|
104
|
+
node._ = data[lang]?.title || data['*']?.title
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (config === null) {
|
|
108
|
+
return node
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Set subpages sources if not exists
|
|
112
|
+
if (node.overview === undefined) {
|
|
113
|
+
node.overview = {
|
|
114
|
+
_translations: meta[lang]?.overview?._translations,
|
|
115
|
+
_sections: meta[lang]?.overview?._sections,
|
|
116
|
+
source: ''
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (config.subpages?.showcase && node.showcase === undefined) {
|
|
120
|
+
node.showcase = {
|
|
121
|
+
_translations: meta[lang]?.showcase?._translations,
|
|
122
|
+
_sections: meta[lang]?.showcase?._sections,
|
|
123
|
+
source: ''
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (config.subpages?.vs && node.vs === undefined) {
|
|
127
|
+
node.vs = {
|
|
128
|
+
_translations: meta[lang]?.vs?._translations,
|
|
129
|
+
_sections: meta[lang]?.vs?._sections,
|
|
130
|
+
source: ''
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return node
|
|
135
|
+
}, i18n[lang]._[topPage])
|
|
136
|
+
|
|
137
|
+
// ---
|
|
138
|
+
|
|
139
|
+
if (config === null || config.status === 'empty') {
|
|
140
|
+
continue
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// @ Subpages
|
|
144
|
+
// Overview
|
|
145
|
+
_.overview.source = load(topPage, path, 'overview', lang)
|
|
146
|
+
// showcase
|
|
147
|
+
if (config.subpages?.showcase === true) {
|
|
148
|
+
_.showcase.source = load(topPage, path, 'showcase', lang)
|
|
149
|
+
}
|
|
150
|
+
// Vs
|
|
151
|
+
if (config.subpages?.vs === true) {
|
|
152
|
+
_.vs.source = load(topPage, path, 'vs', lang)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return i18n
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export default buildMessages
|
package/src/i18n/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// @ Import i18n message builder
|
|
2
|
+
import { buildMessages } from './helpers'
|
|
3
|
+
|
|
1
4
|
// @ Import language HJSON files (Vite-compatible eager import)
|
|
2
5
|
const langModules = import.meta.glob('./languages/*.hjson', { eager: true })
|
|
3
6
|
// @ Import markdown files (Vite-compatible eager import as raw strings)
|
|
@@ -7,120 +10,4 @@ const mdModules = import.meta.glob('../pages/**/*.md', { eager: true, query: '?r
|
|
|
7
10
|
import boot from 'pages/boot'
|
|
8
11
|
import pages from 'pages'
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
'en-US',
|
|
12
|
-
'pt-BR'
|
|
13
|
-
]
|
|
14
|
-
const i18n = {}
|
|
15
|
-
|
|
16
|
-
function filter (source) {
|
|
17
|
-
const regex1 = /{/gm
|
|
18
|
-
const regex2 = /}/gm
|
|
19
|
-
const regex3 = /([@|])+/gm
|
|
20
|
-
|
|
21
|
-
source = source
|
|
22
|
-
.replace(regex1, '{')
|
|
23
|
-
.replace(regex2, '}')
|
|
24
|
-
.replace(regex3, "{'$&'}")
|
|
25
|
-
|
|
26
|
-
return source
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function load (topPage, path, subpage, lang) {
|
|
30
|
-
const key = `../pages/${topPage}/${path}.${subpage}.${lang}.md`
|
|
31
|
-
const content = mdModules[key]
|
|
32
|
-
|
|
33
|
-
if (!content) {
|
|
34
|
-
console.warn(`[i18n] Missing markdown: ${key}`)
|
|
35
|
-
return ''
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const source = filter(typeof content === 'string' ? content : String(content))
|
|
39
|
-
|
|
40
|
-
return source
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// @ Iterate langs
|
|
44
|
-
for (const lang of langs) {
|
|
45
|
-
// Load HJSON language file
|
|
46
|
-
const langKey = `./languages/${lang}.hjson`
|
|
47
|
-
i18n[lang] = langModules[langKey]?.default || langModules[langKey] || {}
|
|
48
|
-
|
|
49
|
-
// @ Iterate pages
|
|
50
|
-
for (const [key, page] of Object.entries(pages)) {
|
|
51
|
-
const path = key.slice(1)
|
|
52
|
-
|
|
53
|
-
const config = page.config
|
|
54
|
-
const data = page.data
|
|
55
|
-
const meta = page.meta || boot.meta
|
|
56
|
-
|
|
57
|
-
const topPage = config?.type ?? 'manual'
|
|
58
|
-
|
|
59
|
-
// ---
|
|
60
|
-
|
|
61
|
-
const _ = path.split('/').reduce((accumulator, current) => {
|
|
62
|
-
let node = accumulator[current]
|
|
63
|
-
|
|
64
|
-
// Set object if not exists
|
|
65
|
-
if (node === undefined) {
|
|
66
|
-
accumulator[current] = {}
|
|
67
|
-
node = accumulator[current]
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// @ Set metadata
|
|
71
|
-
// title
|
|
72
|
-
if (node._ === undefined) {
|
|
73
|
-
node._ = data[lang]?.title || data['*']?.title
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (config === null) {
|
|
77
|
-
return node
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Set subpages sources if not exists
|
|
81
|
-
if (node.overview === undefined) {
|
|
82
|
-
node.overview = {
|
|
83
|
-
_translations: meta[lang]?.overview?._translations,
|
|
84
|
-
_sections: meta[lang]?.overview?._sections,
|
|
85
|
-
source: ''
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
if (config.subpages?.showcase && node.showcase === undefined) {
|
|
89
|
-
node.showcase = {
|
|
90
|
-
_translations: meta[lang]?.showcase?._translations,
|
|
91
|
-
_sections: meta[lang]?.showcase?._sections,
|
|
92
|
-
source: ''
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
if (config.subpages?.vs && node.vs === undefined) {
|
|
96
|
-
node.vs = {
|
|
97
|
-
_translations: meta[lang]?.vs?._translations,
|
|
98
|
-
_sections: meta[lang]?.vs?._sections,
|
|
99
|
-
source: ''
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return node
|
|
104
|
-
}, i18n[lang]._[topPage])
|
|
105
|
-
|
|
106
|
-
// ---
|
|
107
|
-
|
|
108
|
-
if (config === null || config.status === 'empty') {
|
|
109
|
-
continue
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// @ Subpages
|
|
113
|
-
// Overview
|
|
114
|
-
_.overview.source = load(topPage, path, 'overview', lang)
|
|
115
|
-
// showcase
|
|
116
|
-
if (config.subpages?.showcase === true) {
|
|
117
|
-
_.showcase.source = load(topPage, path, 'showcase', lang)
|
|
118
|
-
}
|
|
119
|
-
// Vs
|
|
120
|
-
if (config.subpages?.vs === true) {
|
|
121
|
-
_.vs.source = load(topPage, path, 'vs', lang)
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export default i18n
|
|
13
|
+
export default buildMessages({ langModules, mdModules, pages, boot })
|
|
@@ -33,7 +33,7 @@ import { useRoute, useRouter } from 'vue-router'
|
|
|
33
33
|
import { useStore } from 'vuex'
|
|
34
34
|
import { useI18n } from 'vue-i18n'
|
|
35
35
|
|
|
36
|
-
import DMenu from 'components/DMenu.vue'
|
|
36
|
+
import DMenu from '../components/DMenu.vue'
|
|
37
37
|
import docsectorConfig from 'docsector.config.js'
|
|
38
38
|
|
|
39
39
|
defineOptions({ name: 'LayoutDefault' })
|
|
@@ -10,50 +10,68 @@ Docsector Reader is a **documentation rendering engine** built with Vue 3, Quasa
|
|
|
10
10
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
|
13
|
+
Scaffold a new documentation project with the CLI:
|
|
14
|
+
|
|
13
15
|
```bash
|
|
14
|
-
npx
|
|
16
|
+
npx @docsector/docsector-reader init my-docs
|
|
15
17
|
cd my-docs
|
|
16
18
|
npm install
|
|
17
19
|
```
|
|
18
20
|
|
|
21
|
+
This creates a ready-to-use project with all necessary configuration files, a sample page registry, and i18n setup.
|
|
22
|
+
|
|
19
23
|
## Development Server
|
|
20
24
|
|
|
21
25
|
Start the dev server with hot-reload:
|
|
22
26
|
|
|
23
27
|
```bash
|
|
24
|
-
npx
|
|
28
|
+
npx docsector dev
|
|
25
29
|
```
|
|
26
30
|
|
|
27
31
|
The documentation site will be available at **http://localhost:8181**.
|
|
28
32
|
|
|
33
|
+
You can also specify a custom port:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npx docsector dev --port 3000
|
|
37
|
+
```
|
|
38
|
+
|
|
29
39
|
## Production Build
|
|
30
40
|
|
|
31
41
|
Build an optimized SPA for deployment:
|
|
32
42
|
|
|
33
43
|
```bash
|
|
34
|
-
npx
|
|
44
|
+
npx docsector build
|
|
35
45
|
```
|
|
36
46
|
|
|
37
47
|
The output is placed in `dist/spa/` — ready to deploy to any static hosting.
|
|
38
48
|
|
|
49
|
+
To preview the production build locally:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npx docsector serve
|
|
53
|
+
```
|
|
54
|
+
|
|
39
55
|
## Project Structure
|
|
40
56
|
|
|
41
|
-
|
|
57
|
+
After `init`, your project will have this structure:
|
|
42
58
|
|
|
43
|
-
- `docsector.config.js` — Branding, links, languages
|
|
59
|
+
- `docsector.config.js` — Branding, links, languages, GitHub config
|
|
60
|
+
- `quasar.config.js` — Thin wrapper using `createQuasarConfig()` from the package
|
|
61
|
+
- `index.html` — HTML entry point with title and meta tags
|
|
44
62
|
- `src/pages/index.js` — Page registry (routes and metadata)
|
|
45
63
|
- `src/pages/guide/` — Guide-type pages (Markdown files)
|
|
46
64
|
- `src/pages/manual/` — Manual-type pages (Markdown files)
|
|
47
|
-
- `src/
|
|
48
|
-
- `src/
|
|
49
|
-
- `
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
- `src/boot/` — Boot files (store, i18n, QZoom, axios)
|
|
65
|
+
- `src/i18n/index.js` — i18n loader using `buildMessages()` from the package
|
|
66
|
+
- `src/i18n/tags.hjson` — Search keywords per route and locale
|
|
67
|
+
- `public/` — Static assets (logo, favicon, images)
|
|
68
|
+
|
|
69
|
+
The rendering engine (components, layouts, router, store, composables) lives inside the `@docsector/docsector-reader` package — you only maintain your content and configuration.
|
|
53
70
|
|
|
54
71
|
## Next Steps
|
|
55
72
|
|
|
56
73
|
- Configure your project branding in **docsector.config.js**
|
|
57
74
|
- Define your pages in **src/pages/index.js**
|
|
58
75
|
- Write your documentation in **Markdown**
|
|
76
|
+
- Add search keywords in **src/i18n/tags.hjson**
|
|
59
77
|
- Customize themes and appearance
|
|
@@ -10,50 +10,68 @@ Docsector Reader é um **motor de renderização de documentação** construído
|
|
|
10
10
|
|
|
11
11
|
## Instalação
|
|
12
12
|
|
|
13
|
+
Crie um novo projeto de documentação com o CLI:
|
|
14
|
+
|
|
13
15
|
```bash
|
|
14
|
-
npx
|
|
16
|
+
npx @docsector/docsector-reader init my-docs
|
|
15
17
|
cd my-docs
|
|
16
18
|
npm install
|
|
17
19
|
```
|
|
18
20
|
|
|
21
|
+
Isso cria um projeto pronto para uso com todos os arquivos de configuração, um registro de páginas de exemplo e setup de i18n.
|
|
22
|
+
|
|
19
23
|
## Servidor de Desenvolvimento
|
|
20
24
|
|
|
21
25
|
Inicie o servidor dev com hot-reload:
|
|
22
26
|
|
|
23
27
|
```bash
|
|
24
|
-
npx
|
|
28
|
+
npx docsector dev
|
|
25
29
|
```
|
|
26
30
|
|
|
27
31
|
O site de documentação estará disponível em **http://localhost:8181**.
|
|
28
32
|
|
|
33
|
+
Você também pode especificar uma porta personalizada:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npx docsector dev --port 3000
|
|
37
|
+
```
|
|
38
|
+
|
|
29
39
|
## Build de Produção
|
|
30
40
|
|
|
31
41
|
Gere um SPA otimizado para deploy:
|
|
32
42
|
|
|
33
43
|
```bash
|
|
34
|
-
npx
|
|
44
|
+
npx docsector build
|
|
35
45
|
```
|
|
36
46
|
|
|
37
47
|
O output fica em `dist/spa/` — pronto para deploy em qualquer hosting estático.
|
|
38
48
|
|
|
49
|
+
Para visualizar a build de produção localmente:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npx docsector serve
|
|
53
|
+
```
|
|
54
|
+
|
|
39
55
|
## Estrutura do Projeto
|
|
40
56
|
|
|
41
|
-
|
|
57
|
+
Após o `init`, seu projeto terá esta estrutura:
|
|
42
58
|
|
|
43
|
-
- `docsector.config.js` — Branding, links, idiomas
|
|
59
|
+
- `docsector.config.js` — Branding, links, idiomas, config do GitHub
|
|
60
|
+
- `quasar.config.js` — Wrapper fino usando `createQuasarConfig()` do pacote
|
|
61
|
+
- `index.html` — Ponto de entrada HTML com título e meta tags
|
|
44
62
|
- `src/pages/index.js` — Registro de páginas (rotas e metadata)
|
|
45
63
|
- `src/pages/guide/` — Páginas tipo guia (arquivos Markdown)
|
|
46
64
|
- `src/pages/manual/` — Páginas tipo manual (arquivos Markdown)
|
|
47
|
-
- `src/
|
|
48
|
-
- `src/
|
|
49
|
-
- `
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
- `src/boot/` — Boot files (store, i18n, QZoom, axios)
|
|
65
|
+
- `src/i18n/index.js` — Loader i18n usando `buildMessages()` do pacote
|
|
66
|
+
- `src/i18n/tags.hjson` — Palavras-chave de busca por rota e idioma
|
|
67
|
+
- `public/` — Assets estáticos (logo, favicon, imagens)
|
|
68
|
+
|
|
69
|
+
O motor de renderização (componentes, layouts, router, store, composables) fica dentro do pacote `@docsector/docsector-reader` — você só mantém seu conteúdo e configuração.
|
|
53
70
|
|
|
54
71
|
## Próximos Passos
|
|
55
72
|
|
|
56
73
|
- Configure o branding do seu projeto em **docsector.config.js**
|
|
57
74
|
- Defina suas páginas em **src/pages/index.js**
|
|
58
75
|
- Escreva sua documentação em **Markdown**
|
|
76
|
+
- Adicione palavras-chave de busca em **src/i18n/tags.hjson**
|
|
59
77
|
- Personalize temas e aparência
|