@docsector/docsector-reader 3.2.0 → 3.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.
Files changed (133) hide show
  1. package/README.md +12 -2
  2. package/bin/docsector.js +1 -1
  3. package/package.json +8 -7
  4. package/src/components/DH2.vue +1 -1
  5. package/src/components/DH3.vue +1 -1
  6. package/src/components/DH4.vue +1 -1
  7. package/src/components/DH5.vue +1 -1
  8. package/src/components/DH6.vue +1 -1
  9. package/src/components/DMenu.vue +1 -1
  10. package/src/components/DPage.vue +26 -6
  11. package/src/components/DPageAnchor.vue +3 -9
  12. package/src/components/DPageMeta.vue +1 -0
  13. package/src/components/DPageTokens.vue +5 -5
  14. package/src/components/page-section-tokens.js +19 -1
  15. package/src/composables/useNavigator.js +45 -15
  16. package/src/pages/404Page.vue +2 -2
  17. package/src/pages/Homepage.en-US.md +3 -3
  18. package/src/pages/Homepage.pt-BR.md +3 -3
  19. package/src/pages/guide/i18n-and-markdown.overview.en-US.md +7 -1
  20. package/src/pages/guide/i18n-and-markdown.overview.pt-BR.md +7 -1
  21. package/src/pages/guide/pages-and-routing.overview.en-US.md +11 -9
  22. package/src/pages/guide/pages-and-routing.overview.pt-BR.md +11 -9
  23. package/src/pages/guide.index.js +0 -28
  24. package/src/pages/manual/basic/branding.overview.en-US.md +27 -0
  25. package/src/pages/manual/basic/branding.overview.pt-BR.md +27 -0
  26. package/src/pages/manual/{components → basic}/d-menu.overview.en-US.md +11 -3
  27. package/src/pages/manual/{components → basic}/d-menu.overview.pt-BR.md +11 -3
  28. package/src/pages/manual/{components → basic}/d-page-anchor.overview.en-US.md +5 -3
  29. package/src/pages/manual/{components → basic}/d-page-anchor.overview.pt-BR.md +5 -3
  30. package/src/pages/manual/{components → basic}/d-page-meta.overview.en-US.md +10 -2
  31. package/src/pages/manual/{components → basic}/d-page-meta.overview.pt-BR.md +10 -2
  32. package/src/pages/manual/basic/edit-on-github.overview.en-US.md +26 -0
  33. package/src/pages/manual/basic/edit-on-github.overview.pt-BR.md +26 -0
  34. package/src/pages/manual/basic/previous-and-next.overview.en-US.md +17 -0
  35. package/src/pages/manual/basic/previous-and-next.overview.pt-BR.md +17 -0
  36. package/src/pages/manual/basic/search.overview.en-US.md +24 -0
  37. package/src/pages/manual/basic/search.overview.pt-BR.md +24 -0
  38. package/src/pages/manual/basic/translation-progress.overview.en-US.md +19 -0
  39. package/src/pages/manual/basic/translation-progress.overview.pt-BR.md +19 -0
  40. package/src/pages/manual/basic/version-switcher.overview.en-US.md +28 -0
  41. package/src/pages/manual/basic/version-switcher.overview.pt-BR.md +28 -0
  42. package/src/pages/manual/components/d-subpage.overview.en-US.md +2 -2
  43. package/src/pages/manual/components/d-subpage.overview.pt-BR.md +2 -2
  44. package/src/pages/manual/content/blocks/code-blocks.overview.en-US.md +55 -0
  45. package/src/pages/manual/content/blocks/code-blocks.overview.pt-BR.md +55 -0
  46. package/src/pages/manual/{components/d-page-source-code.showcase.en-US.md → content/blocks/code-blocks.showcase.en-US.md} +14 -12
  47. package/src/pages/manual/{components/d-page-source-code.showcase.pt-BR.md → content/blocks/code-blocks.showcase.pt-BR.md} +28 -26
  48. package/src/pages/manual/{components/d-page-expandable.overview.en-US.md → content/blocks/expandable.overview.en-US.md} +3 -12
  49. package/src/pages/manual/{components/d-page-expandable.overview.pt-BR.md → content/blocks/expandable.overview.pt-BR.md} +3 -12
  50. package/src/pages/manual/content/blocks/headings.overview.en-US.md +45 -0
  51. package/src/pages/manual/content/blocks/headings.overview.pt-BR.md +45 -0
  52. package/src/pages/manual/{components/d-headings.showcase.en-US.md → content/blocks/headings.showcase.en-US.md} +1 -1
  53. package/src/pages/manual/{components/d-headings.showcase.pt-BR.md → content/blocks/headings.showcase.pt-BR.md} +1 -1
  54. package/src/pages/manual/content/blocks/hints.overview.en-US.md +30 -0
  55. package/src/pages/manual/content/blocks/hints.overview.pt-BR.md +30 -0
  56. package/src/pages/manual/content/blocks/hints.showcase.en-US.md +30 -0
  57. package/src/pages/manual/content/blocks/hints.showcase.pt-BR.md +30 -0
  58. package/src/pages/manual/content/blocks/images.overview.en-US.md +16 -0
  59. package/src/pages/manual/content/blocks/images.overview.pt-BR.md +16 -0
  60. package/src/pages/manual/content/blocks/images.showcase.en-US.md +11 -0
  61. package/src/pages/manual/content/blocks/images.showcase.pt-BR.md +11 -0
  62. package/src/pages/manual/content/blocks/math-and-tex.overview.en-US.md +27 -0
  63. package/src/pages/manual/content/blocks/math-and-tex.overview.pt-BR.md +27 -0
  64. package/src/pages/manual/content/blocks/math-and-tex.showcase.en-US.md +14 -0
  65. package/src/pages/manual/content/blocks/math-and-tex.showcase.pt-BR.md +14 -0
  66. package/src/pages/manual/content/blocks/mermaid-diagrams.overview.en-US.md +22 -0
  67. package/src/pages/manual/content/blocks/mermaid-diagrams.overview.pt-BR.md +22 -0
  68. package/src/pages/manual/content/blocks/ordered-lists.overview.en-US.md +19 -0
  69. package/src/pages/manual/content/blocks/ordered-lists.overview.pt-BR.md +19 -0
  70. package/src/pages/manual/content/blocks/ordered-lists.showcase.en-US.md +21 -0
  71. package/src/pages/manual/content/blocks/ordered-lists.showcase.pt-BR.md +21 -0
  72. package/src/pages/manual/content/blocks/paragraphs.overview.en-US.md +19 -0
  73. package/src/pages/manual/content/blocks/paragraphs.overview.pt-BR.md +19 -0
  74. package/src/pages/manual/content/blocks/paragraphs.showcase.en-US.md +9 -0
  75. package/src/pages/manual/content/blocks/paragraphs.showcase.pt-BR.md +9 -0
  76. package/src/pages/manual/content/blocks/quick-links.overview.en-US.md +28 -0
  77. package/src/pages/manual/content/blocks/quick-links.overview.pt-BR.md +28 -0
  78. package/src/pages/manual/content/blocks/quick-links.showcase.en-US.md +34 -0
  79. package/src/pages/manual/content/blocks/quick-links.showcase.pt-BR.md +34 -0
  80. package/src/pages/manual/content/blocks/quotes.overview.en-US.md +24 -0
  81. package/src/pages/manual/content/blocks/quotes.overview.pt-BR.md +24 -0
  82. package/src/pages/manual/content/blocks/quotes.showcase.en-US.md +17 -0
  83. package/src/pages/manual/content/blocks/quotes.showcase.pt-BR.md +17 -0
  84. package/src/pages/manual/content/blocks/raw-html.overview.en-US.md +19 -0
  85. package/src/pages/manual/content/blocks/raw-html.overview.pt-BR.md +19 -0
  86. package/src/pages/manual/content/blocks/raw-html.showcase.en-US.md +12 -0
  87. package/src/pages/manual/content/blocks/raw-html.showcase.pt-BR.md +12 -0
  88. package/src/pages/manual/content/blocks/tables.overview.en-US.md +19 -0
  89. package/src/pages/manual/content/blocks/tables.overview.pt-BR.md +19 -0
  90. package/src/pages/manual/content/blocks/tables.showcase.en-US.md +17 -0
  91. package/src/pages/manual/content/blocks/tables.showcase.pt-BR.md +17 -0
  92. package/src/pages/manual/content/blocks/unordered-lists.overview.en-US.md +21 -0
  93. package/src/pages/manual/content/blocks/unordered-lists.overview.pt-BR.md +21 -0
  94. package/src/pages/manual/content/blocks/unordered-lists.showcase.en-US.md +24 -0
  95. package/src/pages/manual/content/blocks/unordered-lists.showcase.pt-BR.md +24 -0
  96. package/src/pages/manual/content/structures/books.overview.en-US.md +36 -0
  97. package/src/pages/manual/content/structures/books.overview.pt-BR.md +36 -0
  98. package/src/pages/manual/content/structures/page.overview.en-US.md +61 -0
  99. package/src/pages/manual/content/structures/page.overview.pt-BR.md +61 -0
  100. package/src/pages/manual/content/structures/subpage.overview.en-US.md +62 -0
  101. package/src/pages/manual/content/structures/subpage.overview.pt-BR.md +62 -0
  102. package/src/pages/manual.index.js +487 -153
  103. package/src/router/routes.js +1 -1
  104. package/src/pages/guide/alerts-and-blockquotes.overview.en-US.md +0 -65
  105. package/src/pages/guide/alerts-and-blockquotes.overview.pt-BR.md +0 -65
  106. package/src/pages/manual/components/d-headings.overview.en-US.md +0 -54
  107. package/src/pages/manual/components/d-headings.overview.pt-BR.md +0 -54
  108. package/src/pages/manual/components/d-mermaid-diagram.overview.en-US.md +0 -31
  109. package/src/pages/manual/components/d-mermaid-diagram.overview.pt-BR.md +0 -29
  110. package/src/pages/manual/components/d-page-blockquote.overview.en-US.md +0 -66
  111. package/src/pages/manual/components/d-page-blockquote.overview.pt-BR.md +0 -66
  112. package/src/pages/manual/components/d-page-blockquote.showcase.en-US.md +0 -34
  113. package/src/pages/manual/components/d-page-blockquote.showcase.pt-BR.md +0 -34
  114. package/src/pages/manual/components/d-page-section.overview.en-US.md +0 -57
  115. package/src/pages/manual/components/d-page-section.overview.pt-BR.md +0 -57
  116. package/src/pages/manual/components/d-page-section.showcase.en-US.md +0 -43
  117. package/src/pages/manual/components/d-page-section.showcase.pt-BR.md +0 -43
  118. package/src/pages/manual/components/d-page-source-code.overview.en-US.md +0 -68
  119. package/src/pages/manual/components/d-page-source-code.overview.pt-BR.md +0 -68
  120. package/src/pages/manual/components/d-page.overview.en-US.md +0 -59
  121. package/src/pages/manual/components/d-page.overview.pt-BR.md +0 -59
  122. package/src/pages/manual/components/d-page.showcase.en-US.md +0 -35
  123. package/src/pages/manual/components/d-page.showcase.pt-BR.md +0 -35
  124. package/src/pages/manual/components/q-zoom.overview.en-US.md +0 -71
  125. package/src/pages/manual/components/q-zoom.overview.pt-BR.md +0 -71
  126. package/src/pages/manual/composables/use-navigator.overview.en-US.md +0 -89
  127. package/src/pages/manual/composables/use-navigator.overview.pt-BR.md +0 -89
  128. package/src/pages/manual/store/modules.overview.en-US.md +0 -96
  129. package/src/pages/manual/store/modules.overview.pt-BR.md +0 -96
  130. /package/src/pages/manual/{components/d-page-expandable.showcase.en-US.md → content/blocks/expandable.showcase.en-US.md} +0 -0
  131. /package/src/pages/manual/{components/d-page-expandable.showcase.pt-BR.md → content/blocks/expandable.showcase.pt-BR.md} +0 -0
  132. /package/src/pages/manual/{components/d-mermaid-diagram.showcase.en-US.md → content/blocks/mermaid-diagrams.showcase.en-US.md} +0 -0
  133. /package/src/pages/manual/{components/d-mermaid-diagram.showcase.pt-BR.md → content/blocks/mermaid-diagrams.showcase.pt-BR.md} +0 -0
package/README.md CHANGED
@@ -50,7 +50,6 @@ Transform Markdown content into beautiful, navigable documentation sites — wit
50
50
  - 🔗 **Anchor Navigation** — Right-side Table of Contents tree with scroll tracking and auto-scroll to active section
51
51
  - 🖱️ **Active Menu Item UX** — Active menu entries keep pointer cursor, clear URL hash without redundant navigation, and prevent accidental label text selection
52
52
  - 🔎 **Search** — Menu search across all documentation content and tags
53
- - 🌐 **WebMCP Browser Tools** — Registers in-page tools for browser agents with `registerTool` and optional `provideContext` fallback
54
53
  - 📱 **Responsive** — Mobile-friendly with collapsible sidebar and drawers
55
54
  - 📚 **Book Tabs with Per-State Colors** — Define `*.book.js` tabs with icons, order, and `color.active` / `color.inactive`
56
55
  - 🔀 **Internal Shortcut Pages** — Route entries can redirect with `config.link.to`, keeping localized titles while inheriting icon/status from the destination page
@@ -67,6 +66,7 @@ Transform Markdown content into beautiful, navigable documentation sites — wit
67
66
  - 🧭 **Content Signals** — Injects `Content-Signal` policy in `robots.txt` with deterministic, idempotent build output
68
67
  - 🏠 **Markdown Home at Root** — Homepage is rendered from `src/pages/Homepage.{lang}.md` directly at `/`
69
68
  - 🌍 **Remote README as Home** — Optional build-time remote README source for homepage with automatic local fallback
69
+ - 🔗 **GitHub-Compatible Heading Anchors** — Markdown headings use GitHub-style slugs so standard README Table of Contents links work inside Docsector
70
70
  - 🧬 **Scaffolded Homepage Override Wiring** — New consumer projects automatically wire `virtual:docsector-homepage-override` into i18n message building
71
71
  - 📖 **Expandable Markdown Sections** — Use `<d-expandable title="...">...</d-expandable>` to collapse secondary content while keeping rich Markdown support inside the body
72
72
  - 🧭 **Quick Links Custom Element** — Use `<d-quick-links>` and `<d-quick-link>` in Markdown to render rich home navigation cards
@@ -356,6 +356,7 @@ You can configure Docsector Reader to use a remote README as homepage content.
356
356
  - Fetch happens at build-time.
357
357
  - The same README content is used for all configured languages.
358
358
  - If fetch fails, it falls back to local `src/pages/Homepage.{lang}.md` by default.
359
+ - Standard GitHub-style heading links and README Table of Contents fragments keep working in the rendered homepage.
359
360
 
360
361
  ### Configure
361
362
 
@@ -856,7 +857,12 @@ my-docs/
856
857
  │ │ ├── guide.index.js # Guide page registry (routes + metadata)
857
858
  │ │ ├── boot.js # Boot page data
858
859
  │ │ ├── guide/ # Guide pages (.md files)
859
- │ │ └── manual/ # Manual pages (.md files)
860
+ │ │ └── manual/
861
+ │ │ ├── basic/ # Core UI docs exposed in the main manual nav
862
+ │ │ ├── content/
863
+ │ │ │ ├── blocks/ # User-facing Markdown block docs
864
+ │ │ │ └── structures/ # User-facing page structure docs
865
+ │ │ └── components/ # Legacy/internal engine-facing manual docs
860
866
  │ ├── i18n/
861
867
  │ │ ├── index.js # Uses buildMessages() from engine
862
868
  │ │ └── languages/ # HJSON locale files
@@ -870,6 +876,10 @@ my-docs/
870
876
  └── icons/ # PWA icons
871
877
  ```
872
878
 
879
+ A common manual pattern is to keep core UI references under `src/pages/manual/basic/` with user-friendly page titles and focused entry pages such as Search, Branding, Version Switcher, Edit on GitHub, Translation Progress, and Previous & Next, end-user content references under `src/pages/manual/content/blocks/`, structural docs under `src/pages/manual/content/structures/`, and legacy/internal engine-specific references under `src/pages/manual/components/`.
880
+
881
+ Blocks in `src/pages/manual/content/blocks/` should normally provide both `overview` and `showcase` markdown pages, while structural topics can stay overview-only when a visual demo adds little value.
882
+
873
883
  ---
874
884
 
875
885
  ## 📚 Defining Books (Tabs)
package/bin/docsector.js CHANGED
@@ -23,7 +23,7 @@ const packageRoot = resolve(__dirname, '..')
23
23
  const args = process.argv.slice(2)
24
24
  const command = args[0]
25
25
 
26
- const VERSION = '3.2.0'
26
+ const VERSION = '3.2.1'
27
27
 
28
28
  const HELP = `
29
29
  Docsector Reader v${VERSION}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docsector/docsector-reader",
3
- "version": "3.2.0",
3
+ "version": "3.2.1",
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",
@@ -69,6 +69,7 @@
69
69
  "autoprefixer": "^10.4.2",
70
70
  "axios": "^1.7.7",
71
71
  "core-js": "^3.6.5",
72
+ "github-slugger": "^2.0.0",
72
73
  "hjson": "^3.2.2",
73
74
  "katex": "^0.17.0",
74
75
  "markdown-it": "^13.0.1",
@@ -88,11 +89,6 @@
88
89
  },
89
90
  "devDependencies": {
90
91
  "@quasar/extras": "^1.16.12",
91
- "quasar": "^2.16.6",
92
- "vue": "^3.5.13",
93
- "vue-i18n": "^9.0.0",
94
- "vue-router": "^4.0.0",
95
- "vuex": "^4.0.1",
96
92
  "eslint": "^8.57.0",
97
93
  "eslint-config-prettier": "^8.1.0",
98
94
  "eslint-plugin-import": "^2.19.1",
@@ -100,7 +96,12 @@
100
96
  "eslint-plugin-promise": "^6.0.0",
101
97
  "eslint-plugin-vue": "^9.0.0",
102
98
  "prettier": "^2.5.1",
103
- "vitest": "^2.1.8"
99
+ "quasar": "^2.16.6",
100
+ "vitest": "^2.1.8",
101
+ "vue": "^3.5.13",
102
+ "vue-i18n": "^9.0.0",
103
+ "vue-router": "^4.0.0",
104
+ "vuex": "^4.0.1"
104
105
  },
105
106
  "browserslist": [
106
107
  "last 10 Chrome versions",
@@ -5,7 +5,7 @@ import useNavigator from '../composables/useNavigator'
5
5
 
6
6
  const props = defineProps({
7
7
  id: {
8
- type: Number,
8
+ type: [String, Number],
9
9
  required: true
10
10
  },
11
11
  value: {
@@ -5,7 +5,7 @@ import useNavigator from '../composables/useNavigator'
5
5
 
6
6
  const props = defineProps({
7
7
  id: {
8
- type: Number,
8
+ type: [String, Number],
9
9
  required: true
10
10
  },
11
11
  value: {
@@ -5,7 +5,7 @@ import useNavigator from '../composables/useNavigator'
5
5
 
6
6
  const props = defineProps({
7
7
  id: {
8
- type: Number,
8
+ type: [String, Number],
9
9
  required: true
10
10
  },
11
11
  value: {
@@ -5,7 +5,7 @@ import useNavigator from '../composables/useNavigator'
5
5
 
6
6
  const props = defineProps({
7
7
  id: {
8
- type: Number,
8
+ type: [String, Number],
9
9
  required: true
10
10
  },
11
11
  value: {
@@ -5,7 +5,7 @@ import useNavigator from '../composables/useNavigator'
5
5
 
6
6
  const props = defineProps({
7
7
  id: {
8
- type: Number,
8
+ type: [String, Number],
9
9
  required: true
10
10
  },
11
11
  value: {
@@ -162,7 +162,7 @@ const normalizeRoutePath = (path) => {
162
162
  }
163
163
 
164
164
  const getTopRoutes = () => {
165
- return ($router.options.routes || []).slice(0, -2)
165
+ return ($router.options.routes || []).slice(0, -2).filter(route => route?.meta?.menu?.hidden !== true)
166
166
  }
167
167
 
168
168
  const routeHasSubpage = (route, subpageName) => {
@@ -150,11 +150,7 @@ const subroute = (to) => {
150
150
  }
151
151
 
152
152
  if (relative === to) {
153
- if (to !== '/showcase') {
154
- return router.push({ hash: '#0' })
155
- } else {
156
- return router.push({ hash: '#1' })
157
- }
153
+ return router.push({ hash: '#0' })
158
154
  }
159
155
 
160
156
  router.push(path)
@@ -237,6 +233,30 @@ const handleMainScrollKeys = (event) => {
237
233
  container.scrollTop = nextTop
238
234
  }
239
235
 
236
+ const handleContentAnchorClick = (event) => {
237
+ if (event.defaultPrevented || event.button !== 0 || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
238
+ return
239
+ }
240
+
241
+ const target = event.target
242
+ if (!(target instanceof Element)) {
243
+ return
244
+ }
245
+
246
+ const link = target.closest('a[href]')
247
+ if (!link) {
248
+ return
249
+ }
250
+
251
+ const href = link.getAttribute('href') || ''
252
+ if (!href.startsWith('#') || href === '#') {
253
+ return
254
+ }
255
+
256
+ event.preventDefault()
257
+ navigate(href)
258
+ }
259
+
240
260
  const handlePageScroll = (scrollState) => {
241
261
  scrolling(scrollState)
242
262
  syncReadingProgress(scrollState?.position?.top)
@@ -327,7 +347,7 @@ watch(() => route.fullPath, () => {
327
347
 
328
348
  <q-page id="page">
329
349
  <q-scroll-area class="content" :class="main" ref="pageScrollArea">
330
- <div id="scroll-container">
350
+ <div id="scroll-container" @click="handleContentAnchorClick">
331
351
  <slot />
332
352
  </div>
333
353
  <d-page-meta v-if="!disableNav" />
@@ -21,19 +21,13 @@ const expanded = computed({
21
21
  get() {
22
22
  return store.getters['page/nodesExpanded']
23
23
  },
24
- set(value) {
24
+ set() {
25
25
  // console.log(value)
26
26
  }
27
27
  })
28
28
  const selected = computed({
29
29
  get() {
30
- let anchor = store.state.page.anchor
31
-
32
- if (store.state.page.relative !== '' && anchor === 0) {
33
- anchor = anchor + 1
34
- }
35
-
36
- return anchor
30
+ return store.state.page.anchor
37
31
  },
38
32
  set(value) {
39
33
  navigate(value)
@@ -90,7 +84,7 @@ onMounted(() => {
90
84
  const id = route.hash.replace(/^#+/g, '')
91
85
  if (id) {
92
86
  setTimeout(() => {
93
- anchor(id)
87
+ anchor(route.hash)
94
88
  }, 500)
95
89
  }
96
90
  })
@@ -156,6 +156,7 @@ const getVersionSiblingPath = (offset) => {
156
156
  const currentPath = normalizeRoutePath(route.matched?.[0]?.path || `/${store.state.page.base}`)
157
157
  const routes = router.options.routes
158
158
  .slice(0, -2)
159
+ .filter(item => item?.meta?.menu?.hidden !== true)
159
160
  .filter(item => !versionId || item?.meta?.version === versionId)
160
161
 
161
162
  const index = routes.findIndex(item => normalizeRoutePath(item.path) === currentPath)
@@ -30,27 +30,27 @@ import DPageExpandable from './DPageExpandable.vue'
30
30
  <template v-for="(token, index) in tokens" :key="`${token.tag}-${index}`">
31
31
  <d-h2
32
32
  v-if="token.tag === 'h2'"
33
- :id="id + token.map[0]"
33
+ :id="token.anchorId"
34
34
  :value="token.content"
35
35
  />
36
36
  <d-h3
37
37
  v-else-if="token.tag === 'h3'"
38
- :id="id + token.map[0]"
38
+ :id="token.anchorId"
39
39
  :value="token.content"
40
40
  />
41
41
  <d-h4
42
42
  v-else-if="token.tag === 'h4'"
43
- :id="id + token.map[0]"
43
+ :id="token.anchorId"
44
44
  :value="token.content"
45
45
  />
46
46
  <d-h5
47
47
  v-else-if="token.tag === 'h5'"
48
- :id="id + token.map[0]"
48
+ :id="token.anchorId"
49
49
  :value="token.content"
50
50
  />
51
51
  <d-h6
52
52
  v-else-if="token.tag === 'h6'"
53
- :id="id + token.map[0]"
53
+ :id="token.anchorId"
54
54
  :value="token.content"
55
55
  />
56
56
 
@@ -1,5 +1,6 @@
1
1
  import MarkdownIt from 'markdown-it'
2
2
  import attrs from 'markdown-it-attrs'
3
+ import GithubSlugger from 'github-slugger'
3
4
  import katex from 'katex'
4
5
  import texmath from 'markdown-it-texmath'
5
6
 
@@ -346,10 +347,24 @@ const normalizePageSectionSource = (source = '') => {
346
347
  .replace(/&amp;/g, '&')
347
348
  }
348
349
 
350
+ const createParserState = () => ({
351
+ codeIndex: 0,
352
+ headingSlugger: new GithubSlugger()
353
+ })
354
+
355
+ const getHeadingAnchorId = (markdown, currentTag, element, env, parserState) => {
356
+ if (!currentTag || !currentTag.match(/^h[2-6]$/)) {
357
+ return ''
358
+ }
359
+
360
+ const headingText = markdown.renderer.renderInlineAsText(element.children || [], markdown.options, env).trim()
361
+ return parserState.headingSlugger.slug(headingText)
362
+ }
363
+
349
364
  export const tokenizePageSectionSource = (source = '', options = {}) => {
350
365
  const {
351
366
  allowHeadingTokens = true,
352
- parserState = { codeIndex: 0 }
367
+ parserState = createParserState()
353
368
  } = options
354
369
  const normalizedSource = normalizePageSectionSource(source)
355
370
  const { source: sourceWithShieldedCode, codeSegmentsMap } = shieldMarkdownCodeSegments(normalizedSource)
@@ -506,6 +521,8 @@ export const tokenizePageSectionSource = (source = '', options = {}) => {
506
521
 
507
522
  switch (element.type) {
508
523
  case 'inline':
524
+ const anchorId = getHeadingAnchorId(markdown, tag, element, markdownEnv, parserState)
525
+
509
526
  if (expandableMap.has(element.content.trim())) {
510
527
  const data = expandableMap.get(element.content.trim())
511
528
 
@@ -535,6 +552,7 @@ export const tokenizePageSectionSource = (source = '', options = {}) => {
535
552
  tokens.push({
536
553
  tag,
537
554
  map: element.map,
555
+ anchorId,
538
556
  content: element.content,
539
557
  info: element.info
540
558
  })
@@ -9,13 +9,34 @@ export default function useNavigator() {
9
9
  const route = useRoute()
10
10
  const selected = ref(null)
11
11
 
12
+ const normalizeDomAnchorId = (id) => {
13
+ if (id === null || id === undefined || id === false) {
14
+ return ''
15
+ }
16
+
17
+ let normalized = String(id).replace(/^#+/g, '')
18
+
19
+ try {
20
+ normalized = decodeURIComponent(normalized)
21
+ } catch {
22
+ // Keep the raw fragment when it is not valid percent-encoding.
23
+ }
24
+
25
+ return normalized
26
+ }
27
+
28
+ const normalizeStoreAnchorId = (id) => {
29
+ const normalized = normalizeDomAnchorId(id)
30
+ return normalized === '0' ? 0 : normalized
31
+ }
32
+
12
33
  const register = (id) => {
13
- store.commit('page/pushAnchors', id)
34
+ store.commit('page/pushAnchors', normalizeStoreAnchorId(id))
14
35
  }
15
36
 
16
37
  const index = (id, child = false) => {
17
38
  store.commit('page/pushNodes', {
18
- id,
39
+ id: normalizeStoreAnchorId(id),
19
40
  label: selected.value,
20
41
  child,
21
42
  children: []
@@ -23,15 +44,17 @@ export default function useNavigator() {
23
44
  }
24
45
 
25
46
  const select = (id) => {
26
- store.commit('page/setAnchor', Number(id))
27
- store.commit('page/pushNodesExpanded', Number(id))
47
+ const normalized = normalizeStoreAnchorId(id)
48
+
49
+ store.commit('page/setAnchor', normalized)
50
+ store.commit('page/pushNodesExpanded', normalized)
28
51
  }
29
52
 
30
53
  const anchor = (id, toSelect = true) => {
31
54
  store.commit('page/setScrolling', false)
32
55
 
33
- id = '' + id
34
- const Anchor = document.getElementById(id)
56
+ const anchorId = normalizeDomAnchorId(id)
57
+ const Anchor = document.getElementById(anchorId)
35
58
 
36
59
  if (Anchor !== null && typeof Anchor === 'object') {
37
60
  const ScrollTarget = scroll.getScrollTarget(Anchor)
@@ -45,7 +68,7 @@ export default function useNavigator() {
45
68
  }
46
69
 
47
70
  if (toSelect) {
48
- select(id)
71
+ select(anchorId)
49
72
  }
50
73
  }
51
74
 
@@ -60,12 +83,13 @@ export default function useNavigator() {
60
83
 
61
84
  for (let i = 0; i < anchors.length; i++) {
62
85
  const anchorId = anchors[i]
86
+ const domAnchorId = normalizeDomAnchorId(anchorId)
63
87
 
64
- if (anchorId === 0) {
88
+ if (domAnchorId === '0') {
65
89
  continue
66
90
  }
67
91
 
68
- const Anchor = document.getElementById(anchorId)
92
+ const Anchor = document.getElementById(domAnchorId)
69
93
  let AnchorOffsetTop = 20
70
94
  if (Anchor !== null && typeof Anchor === 'object') {
71
95
  AnchorOffsetTop = Anchor.offsetTop
@@ -78,24 +102,30 @@ export default function useNavigator() {
78
102
  }
79
103
 
80
104
  const navigate = (value, toAnchor = true) => {
105
+ const domAnchorId = normalizeDomAnchorId(value)
106
+ const currentRouteAnchorId = normalizeDomAnchorId(route.hash)
107
+
81
108
  if (toAnchor) {
82
- if (('#' + value) === route.hash) {
83
- anchor(value)
109
+ if (domAnchorId !== '' && domAnchorId === currentRouteAnchorId) {
110
+ anchor(domAnchorId)
84
111
  return
85
112
  } else if (value === null) {
86
- anchor(selected.value, false)
113
+ anchor(store.state.page.anchor, false)
87
114
  return
88
115
  }
89
116
  }
90
117
 
91
- router.push(route.path + '#' + value)
118
+ router.push({
119
+ path: route.path,
120
+ hash: domAnchorId === '' ? '' : `#${domAnchorId}`
121
+ })
92
122
 
93
123
  if (toAnchor) {
94
124
  if (Platform.is.desktop) {
95
- anchor(value)
125
+ anchor(domAnchorId)
96
126
  } else {
97
127
  setTimeout(() => {
98
- anchor(value)
128
+ anchor(domAnchorId)
99
129
  }, 600)
100
130
  }
101
131
  }
@@ -3,12 +3,12 @@
3
3
  <q-page class="row" padding>
4
4
  <q-scroll-area class="content col text-center">
5
5
  <p>
6
- <img src="sad.svg" style="width:30vw;max-width:150px;" />
6
+ <img src="/sad.svg" alt="404 illustration" style="width:30vw;max-width:150px;" />
7
7
  </p>
8
8
  <p class="text-faded">Sorry, nothing here...
9
9
  <strong>(404)</strong>
10
10
  </p>
11
- <q-btn color="secondary" style="width:200px;" @click="$router.go(-1)">Go back</q-btn>
11
+ <q-btn color="secondary" style="width:200px;" @click="$router.push('/')">Go home</q-btn>
12
12
  </q-scroll-area>
13
13
  </q-page>
14
14
  </q-page-container>
@@ -7,9 +7,9 @@ Docsector Reader is a documentation rendering engine built with Vue 3, Quasar v2
7
7
  - [Getting Started](/guide/getting-started/overview/)
8
8
  - [Configuration](/guide/configuration/overview/)
9
9
  - [Pages and Routing](/guide/pages-and-routing/overview/)
10
- - [Components](/manual/components/d-page/overview/)
11
- - [Composables](/manual/composables/use-navigator/overview/)
12
- - [Store Modules](/manual/store/modules/overview/)
10
+ - [Basic](/manual/basic/d-menu/overview/)
11
+ - [Content](/manual/content/blocks/paragraphs/overview/)
12
+ - [Structures](/manual/content/structures/books/overview/)
13
13
 
14
14
  ## About
15
15
 
@@ -7,9 +7,9 @@ Docsector Reader e um motor de documentacao construído com Vue 3, Quasar v2 e V
7
7
  - [Comecando](/guide/getting-started/overview/)
8
8
  - [Configuracao](/guide/configuration/overview/)
9
9
  - [Paginas e Rotas](/guide/pages-and-routing/overview/)
10
- - [Componentes](/manual/components/d-page/overview/)
11
- - [Composables](/manual/composables/use-navigator/overview/)
12
- - [Modulos de Store](/manual/store/modules/overview/)
10
+ - [Básico](/manual/basic/d-menu/overview/)
11
+ - [Conteúdo](/manual/content/blocks/paragraphs/overview/)
12
+ - [Estruturas](/manual/content/structures/books/overview/)
13
13
 
14
14
  ## Sobre
15
15
 
@@ -41,9 +41,15 @@ The `_` object is the root namespace for pages. Page titles and content are **au
41
41
 
42
42
  Documentation content is written in standard Markdown with some conventions:
43
43
 
44
+ See the dedicated manual pages for block-by-block reference:
45
+
46
+ - [Paragraphs](/manual/content/blocks/paragraphs/overview/), [Headings](/manual/content/blocks/headings/overview/), [Unordered lists](/manual/content/blocks/unordered-lists/overview/), [Ordered lists](/manual/content/blocks/ordered-lists/overview/)
47
+ - [Hints](/manual/content/blocks/hints/overview/), [Quote](/manual/content/blocks/quotes/overview/), [Code blocks](/manual/content/blocks/code-blocks/overview/), [Mermaid diagrams](/manual/content/blocks/mermaid-diagrams/overview/)
48
+ - [Images](/manual/content/blocks/images/overview/), [Math & TeX](/manual/content/blocks/math-and-tex/overview/), [Expandable](/manual/content/blocks/expandable/overview/), [Tables](/manual/content/blocks/tables/overview/), [Raw HTML](/manual/content/blocks/raw-html/overview/), and [Quick Links](/manual/content/blocks/quick-links/overview/)
49
+
44
50
  ### Headings
45
51
 
46
- Use `##` through `######` for section headings. Each heading becomes a navigation anchor in the ToC tree.
52
+ Use `##` through `######` for section headings. Each heading becomes a navigation anchor in the ToC tree using a GitHub-compatible slug, so standard README fragments such as `#table-of-contents` work in Docsector too.
47
53
 
48
54
  ### Code Blocks
49
55
 
@@ -41,9 +41,15 @@ O objeto `_` é o namespace raiz para páginas. Títulos e conteúdo das página
41
41
 
42
42
  O conteúdo da documentação é escrito em Markdown padrão com algumas convenções:
43
43
 
44
+ Veja também as páginas dedicadas do manual para cada bloco:
45
+
46
+ - [Parágrafos](/manual/content/blocks/paragraphs/overview/), [Títulos](/manual/content/blocks/headings/overview/), [Listas não ordenadas](/manual/content/blocks/unordered-lists/overview/), [Listas ordenadas](/manual/content/blocks/ordered-lists/overview/)
47
+ - [Hints](/manual/content/blocks/hints/overview/), [Citação](/manual/content/blocks/quotes/overview/), [Blocos de código](/manual/content/blocks/code-blocks/overview/), [Diagramas Mermaid](/manual/content/blocks/mermaid-diagrams/overview/)
48
+ - [Imagens](/manual/content/blocks/images/overview/), [Math & TeX](/manual/content/blocks/math-and-tex/overview/), [Expansível](/manual/content/blocks/expandable/overview/), [Tabelas](/manual/content/blocks/tables/overview/), [HTML bruto](/manual/content/blocks/raw-html/overview/) e [Quick Links](/manual/content/blocks/quick-links/overview/)
49
+
44
50
  ### Títulos
45
51
 
46
- Use `##` até `######` para títulos de seção. Cada título se torna uma âncora de navegação na árvore de ToC.
52
+ Use `##` até `######` para títulos de seção. Cada título se torna uma âncora de navegação na árvore de ToC usando slug compatível com GitHub, então fragmentos padrão de README como `#table-of-contents` também funcionam no Docsector.
47
53
 
48
54
  ### Blocos de Código
49
55
 
@@ -2,6 +2,8 @@
2
2
 
3
3
  Documentation pages are defined in split registries such as `src/pages/guide.index.js` and `src/pages/manual.index.js`. Each entry maps a URL path to its configuration, translatable data, and optional metadata.
4
4
 
5
+ In the current manual, it is common to keep core UI references under `/basic`, end-user content blocks under `/content/blocks`, structural concepts under `/content/structures`, and legacy engine-facing aliases under `/components`.
6
+
5
7
  ## Page Entry Structure
6
8
 
7
9
  ```javascript
@@ -35,11 +37,11 @@ Documentation pages are defined in split registries such as `src/pages/guide.ind
35
37
  Set `config: null` to create a non-navigable grouping node. This is useful for creating section titles in the sidebar menu:
36
38
 
37
39
  ```javascript
38
- '/components': &#123;
40
+ '/content/blocks': &#123;
39
41
  config: null,
40
42
  data: &#123;
41
- 'en-US': &#123; title: 'Components' &#125;,
42
- 'pt-BR': &#123; title: 'Componentes' &#125;
43
+ 'en-US': &#123; title: 'Blocks' &#125;,
44
+ 'pt-BR': &#123; title: 'Blocos' &#125;
43
45
  &#125;
44
46
  &#125;
45
47
  ```
@@ -51,8 +53,8 @@ Pages are grouped in the sidebar by their **basepath** (second URL segment). The
51
53
  ```javascript
52
54
  menu: &#123;
53
55
  header: &#123;
54
- icon: 'widgets',
55
- label: 'Components'
56
+ icon: 'notes',
57
+ label: 'Content'
56
58
  &#125;
57
59
  &#125;
58
60
  ```
@@ -72,11 +74,11 @@ Each page requires Markdown files following this naming pattern:
72
74
 
73
75
  `src/pages/&#123;book&#125;/&#123;path&#125;.&#123;subpage&#125;.&#123;lang&#125;.md`
74
76
 
75
- For example, a page at `/components/d-page` with book `manual`:
77
+ For example, a page at `/content/blocks/headings` with book `manual`:
76
78
 
77
- - `src/pages/manual/components/d-page.overview.en-US.md`
78
- - `src/pages/manual/components/d-page.overview.pt-BR.md`
79
- - `src/pages/manual/components/d-page.showcase.en-US.md` (if showcase enabled)
79
+ - `src/pages/manual/content/blocks/headings.overview.en-US.md`
80
+ - `src/pages/manual/content/blocks/headings.overview.pt-BR.md`
81
+ - `src/pages/manual/content/blocks/headings.showcase.en-US.md` (if showcase enabled)
80
82
 
81
83
  ## Route Generation
82
84
 
@@ -2,6 +2,8 @@
2
2
 
3
3
  As páginas de documentação são definidas em registros separados, como `src/pages/guide.index.js` e `src/pages/manual.index.js`. Cada entrada mapeia um caminho URL para sua configuração, dados traduzíveis e metadata opcional.
4
4
 
5
+ No manual atual, é comum manter referências centrais de UI sob `/basic`, blocos de conteúdo voltados ao usuário final sob `/content/blocks`, conceitos estruturais sob `/content/structures` e aliases legados voltados à engine sob `/components`.
6
+
5
7
  ## Estrutura de uma Entrada
6
8
 
7
9
  ```javascript
@@ -35,11 +37,11 @@ As páginas de documentação são definidas em registros separados, como `src/p
35
37
  Defina `config: null` para criar um nó de agrupamento não-navegável. Útil para criar títulos de seção no menu lateral:
36
38
 
37
39
  ```javascript
38
- '/components': &#123;
40
+ '/content/blocks': &#123;
39
41
  config: null,
40
42
  data: &#123;
41
- 'en-US': &#123; title: 'Components' &#125;,
42
- 'pt-BR': &#123; title: 'Componentes' &#125;
43
+ 'en-US': &#123; title: 'Blocks' &#125;,
44
+ 'pt-BR': &#123; title: 'Blocos' &#125;
43
45
  &#125;
44
46
  &#125;
45
47
  ```
@@ -51,8 +53,8 @@ Páginas são agrupadas no menu lateral pelo seu **basepath** (segundo segmento
51
53
  ```javascript
52
54
  menu: &#123;
53
55
  header: &#123;
54
- icon: 'widgets',
55
- label: 'Components'
56
+ icon: 'notes',
57
+ label: 'Conteúdo'
56
58
  &#125;
57
59
  &#125;
58
60
  ```
@@ -72,11 +74,11 @@ Cada página requer arquivos Markdown seguindo este padrão de nomenclatura:
72
74
 
73
75
  `src/pages/&#123;book&#125;/&#123;path&#125;.&#123;subpage&#125;.&#123;lang&#125;.md`
74
76
 
75
- Por exemplo, uma página em `/components/d-page` com book `manual`:
77
+ Por exemplo, uma página em `/content/blocks/headings` com book `manual`:
76
78
 
77
- - `src/pages/manual/components/d-page.overview.en-US.md`
78
- - `src/pages/manual/components/d-page.overview.pt-BR.md`
79
- - `src/pages/manual/components/d-page.showcase.en-US.md` (se showcase habilitado)
79
+ - `src/pages/manual/content/blocks/headings.overview.en-US.md`
80
+ - `src/pages/manual/content/blocks/headings.overview.pt-BR.md`
81
+ - `src/pages/manual/content/blocks/headings.showcase.en-US.md` (se showcase habilitado)
80
82
 
81
83
  ## Geração de Rotas
82
84