@md-plugins/quasar-app-extension-q-press 0.1.0-beta.12 → 0.1.0-beta.14
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 +12 -5
- package/dist/templates/init/src/_q-press/components/MarkdownCodepen.vue +25 -4
- package/dist/templates/init/src/_q-press/components/markdown-utils.ts +27 -3
- package/dist/templates/init/src/_q-press/layouts/MarkdownDrawerSidebar.vue +1 -1
- package/dist/templates/init/src/_q-press/layouts/MarkdownDrawerToc.vue +1 -1
- package/dist/templates/init/src/_q-press/layouts/MarkdownLayout.vue +1 -1
- package/dist/templates/init/src/markdown/__elements.md +6 -6
- package/dist/templates/init/src/markdown/__elements2.md +2 -2
- package/dist/templates/init/src/markdown/md-plugins/codeblocks/overview.md +4 -4
- package/dist/templates/init/src/markdown/md-plugins/link/advanced.md +2 -2
- package/dist/templates/init/src/markdown/md-plugins/link/overview.md +3 -3
- package/dist/templates/init/src/markdown/md-plugins/shared/overview.md +12 -8
- package/dist/templates/init/src/markdown/quasar-app-extensions/qpress/components.md +23 -23
- package/dist/templates/init/src/markdown/quasar-app-extensions/qpress/overview.md +5 -5
- package/dist/templates/init/src/markdown/vite-plugins/vite-md-plugin/overview.md +1 -1
- package/dist/templates/init/src/siteConfig/index.ts +1 -1
- package/dist/templates/update/src/_q-press/components/MarkdownCodepen.vue +25 -4
- package/dist/templates/update/src/_q-press/components/markdown-utils.ts +27 -3
- package/dist/templates/update/src/_q-press/layouts/MarkdownDrawerSidebar.vue +1 -1
- package/dist/templates/update/src/_q-press/layouts/MarkdownDrawerToc.vue +1 -1
- package/dist/templates/update/src/_q-press/layouts/MarkdownLayout.vue +1 -1
- package/package.json +14 -15
- package/src/templates/init/src/_q-press/components/MarkdownCodepen.vue +25 -4
- package/src/templates/init/src/_q-press/components/markdown-utils.ts +27 -3
- package/src/templates/init/src/_q-press/layouts/MarkdownDrawerSidebar.vue +1 -1
- package/src/templates/init/src/_q-press/layouts/MarkdownDrawerToc.vue +1 -1
- package/src/templates/init/src/_q-press/layouts/MarkdownLayout.vue +1 -1
- package/src/templates/init/src/markdown/__elements.md +6 -6
- package/src/templates/init/src/markdown/__elements2.md +2 -2
- package/src/templates/init/src/markdown/md-plugins/codeblocks/overview.md +4 -4
- package/src/templates/init/src/markdown/md-plugins/link/advanced.md +2 -2
- package/src/templates/init/src/markdown/md-plugins/link/overview.md +3 -3
- package/src/templates/init/src/markdown/md-plugins/shared/overview.md +12 -8
- package/src/templates/init/src/markdown/quasar-app-extensions/qpress/components.md +23 -23
- package/src/templates/init/src/markdown/quasar-app-extensions/qpress/overview.md +5 -5
- package/src/templates/init/src/markdown/vite-plugins/vite-md-plugin/overview.md +1 -1
- package/src/templates/init/src/siteConfig/index.ts +1 -1
- package/src/templates/update/src/_q-press/components/MarkdownCodepen.vue +25 -4
- package/src/templates/update/src/_q-press/components/markdown-utils.ts +27 -3
- package/src/templates/update/src/_q-press/layouts/MarkdownDrawerSidebar.vue +1 -1
- package/src/templates/update/src/_q-press/layouts/MarkdownDrawerToc.vue +1 -1
- package/src/templates/update/src/_q-press/layouts/MarkdownLayout.vue +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ The Ultimate Markdown Solution for the Quasar Framework.
|
|
|
4
4
|
|
|
5
5
|
See the [documentation](https://md-plugins.netlify.app/quasar-app-extensions/qpress/overview) for more information.
|
|
6
6
|
|
|
7
|
-
> Current beta release: `0.1.0-beta.
|
|
7
|
+
> Current beta release: `0.1.0-beta.13`.
|
|
8
8
|
>
|
|
9
9
|
> Q-Press currently targets Quasar Vite projects using `@quasar/app-vite` `>=3.0.0-beta.30`. TypeScript processing is required.
|
|
10
10
|
|
|
@@ -92,11 +92,11 @@ See the [documentation](https://md-plugins.netlify.app/quasar-app-extensions/qpr
|
|
|
92
92
|
|
|
93
93
|
- ```ts
|
|
94
94
|
import type { RouteRecordRaw } from 'vue-router'
|
|
95
|
-
import mdPageList from '
|
|
95
|
+
import mdPageList from '@/markdown/listing'
|
|
96
96
|
const routes = [
|
|
97
97
|
{
|
|
98
98
|
path: '/',
|
|
99
|
-
component: () => import('
|
|
99
|
+
component: () => import('@/.q-press/layouts/MarkdownLayout.vue'),
|
|
100
100
|
children: [
|
|
101
101
|
// Include the Landing Page route first
|
|
102
102
|
...Object.entries(mdPageList)
|
|
@@ -134,7 +134,7 @@ See the [documentation](https://md-plugins.netlify.app/quasar-app-extensions/qpr
|
|
|
134
134
|
// but you can also remove it
|
|
135
135
|
{
|
|
136
136
|
path: '/:catchAll(.*)*',
|
|
137
|
-
component: () => import('pages/ErrorNotFound.vue'),
|
|
137
|
+
component: () => import('@/pages/ErrorNotFound.vue'),
|
|
138
138
|
},
|
|
139
139
|
] as RouteRecordRaw[]
|
|
140
140
|
|
|
@@ -149,7 +149,7 @@ See the [documentation](https://md-plugins.netlify.app/quasar-app-extensions/qpr
|
|
|
149
149
|
</template>
|
|
150
150
|
|
|
151
151
|
<script setup lang="ts">
|
|
152
|
-
import { useDark } from '
|
|
152
|
+
import { useDark } from '@/.q-press/composables/dark'
|
|
153
153
|
const { initDark } = useDark()
|
|
154
154
|
initDark()
|
|
155
155
|
</script>
|
|
@@ -232,6 +232,13 @@ quasar ext invoke @md-plugins/q-press
|
|
|
232
232
|
|
|
233
233
|
In case this README falls out of date, please refer to the [documentation](https://md-plugins.netlify.app/quasar-app-extensions/qpress/overview) for the latest information.
|
|
234
234
|
|
|
235
|
+
## Support
|
|
236
|
+
|
|
237
|
+
If Q-Press is useful in your workflow and you want to support ongoing maintenance:
|
|
238
|
+
|
|
239
|
+
GitHub Sponsors: https://github.com/sponsors/hawkeye64
|
|
240
|
+
PayPal: https://paypal.me/hawkeye64
|
|
241
|
+
|
|
235
242
|
## License
|
|
236
243
|
|
|
237
244
|
This project is licensed under the MIT License. See the [LICENSE](LICENSE.md) file for details.
|
|
@@ -15,9 +15,8 @@
|
|
|
15
15
|
import { Quasar } from 'quasar'
|
|
16
16
|
import { ref, reactive, computed, nextTick } from 'vue'
|
|
17
17
|
|
|
18
|
-
import { slugify } from '@md-plugins/shared'
|
|
19
|
-
|
|
20
18
|
import siteConfig from '../../siteConfig'
|
|
19
|
+
import { slugify } from './markdown-utils'
|
|
21
20
|
|
|
22
21
|
type CodepenParts = {
|
|
23
22
|
Template?: string
|
|
@@ -41,6 +40,26 @@ const defaultJsResources = [
|
|
|
41
40
|
`https://cdn.jsdelivr.net/npm/quasar@${Quasar.version}/dist/quasar.umd.prod.js`,
|
|
42
41
|
]
|
|
43
42
|
|
|
43
|
+
function getAbsolutePublicUrl(path: string) {
|
|
44
|
+
const normalizedPath = path.startsWith('/') ? path : `/${path}`
|
|
45
|
+
|
|
46
|
+
return typeof location === 'undefined' ? normalizedPath : `${location.origin}${normalizedPath}`
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function rewriteRootRelativeUrls(content: string) {
|
|
50
|
+
return content
|
|
51
|
+
.replace(
|
|
52
|
+
/\b(src|href|poster)=("|')\/(?!\/)([^"']*)\2/g,
|
|
53
|
+
(_match: string, attr: string, quote: string, path: string) =>
|
|
54
|
+
`${attr}=${quote}${getAbsolutePublicUrl(path)}${quote}`,
|
|
55
|
+
)
|
|
56
|
+
.replace(
|
|
57
|
+
/url\(\s*(["']?)\/(?!\/)([^"')]+)\1\s*\)/g,
|
|
58
|
+
(_match: string, quote: string, path: string) =>
|
|
59
|
+
`url(${quote}${getAbsolutePublicUrl(path)}${quote})`,
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
44
63
|
function indent(code: string, spaces = 2) {
|
|
45
64
|
const padding = ' '.repeat(spaces)
|
|
46
65
|
return code
|
|
@@ -271,7 +290,7 @@ const jsResources = computed(() => {
|
|
|
271
290
|
})
|
|
272
291
|
|
|
273
292
|
const css = computed(() => {
|
|
274
|
-
return (def.parts.Style || '').replace(/(<style.*?>|<\/style>)/g, '').trim()
|
|
293
|
+
return rewriteRootRelativeUrls((def.parts.Style || '').replace(/(<style.*?>|<\/style>)/g, '').trim())
|
|
275
294
|
})
|
|
276
295
|
|
|
277
296
|
const cssPreprocessor = computed(() => {
|
|
@@ -297,7 +316,7 @@ const jsPreProcessor = computed(() => {
|
|
|
297
316
|
})
|
|
298
317
|
|
|
299
318
|
const html = computed(() => {
|
|
300
|
-
|
|
319
|
+
const content = (def.parts.Template || '')
|
|
301
320
|
.replace(/(<template>|<\/template>$)/g, '')
|
|
302
321
|
.replace(/\n/g, '\n ')
|
|
303
322
|
.replace(/([\w]+=")([^"]*?)(")/g, function (match, p1, p2, p3) {
|
|
@@ -331,6 +350,8 @@ const html = computed(() => {
|
|
|
331
350
|
.replace(/___TEMP_REPLACEMENT___/g, '>')
|
|
332
351
|
.replace(/^\s{2}/gm, '')
|
|
333
352
|
.trim()
|
|
353
|
+
|
|
354
|
+
return rewriteRootRelativeUrls(content)
|
|
334
355
|
})
|
|
335
356
|
|
|
336
357
|
const editors = computed(() => {
|
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
import { Notify } from 'quasar'
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
const andRE = /&/g
|
|
4
|
+
const rCombining = /[\u0300-\u036F]/g
|
|
5
|
+
// oxlint-disable-next-line no-control-regex
|
|
6
|
+
const rControl = /[\u0000-\u001f]/g
|
|
7
|
+
const rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'“”‘’<>,.?/]+/g
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Default slugification function used by qPress client helpers.
|
|
11
|
+
*/
|
|
12
|
+
export const slugify = (str: string): string =>
|
|
13
|
+
str
|
|
14
|
+
.trim()
|
|
15
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
16
|
+
.replace(/[\s_]+/g, '-')
|
|
17
|
+
.toLowerCase()
|
|
18
|
+
.normalize('NFKD')
|
|
19
|
+
.replace(rCombining, '')
|
|
20
|
+
.replace(andRE, '-and-')
|
|
21
|
+
.replace(rControl, '-')
|
|
22
|
+
.replace(rSpecial, '-')
|
|
23
|
+
.replace(/[^a-z0-9-]+/g, '')
|
|
24
|
+
.replace(/([a-z])(\d)/g, '$1-$2')
|
|
25
|
+
.replace(/(\d)([a-z])/g, '$1-$2')
|
|
26
|
+
.replace(/-{2,}/g, '-')
|
|
27
|
+
.replace(/(^-|-$)/g, '')
|
|
28
|
+
.replace(/^(\d)/, '_$1')
|
|
3
29
|
|
|
4
30
|
/**
|
|
5
31
|
* Fallback function to copy text to clipboard when the Clipboard API is not available.
|
|
@@ -101,5 +127,3 @@ export function copyHeading(id: string): void {
|
|
|
101
127
|
timeout: 2000,
|
|
102
128
|
})
|
|
103
129
|
}
|
|
104
|
-
|
|
105
|
-
export { slugify }
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<script setup lang="ts">
|
|
26
26
|
import { mdiClose } from '@quasar/extras/mdi-v7'
|
|
27
27
|
|
|
28
|
-
import { useMarkdownStore } from '
|
|
28
|
+
import { useMarkdownStore } from '@/.q-press/stores/markdown'
|
|
29
29
|
import MarkdownPageSidebar from './MarkdownPageSidebar'
|
|
30
30
|
|
|
31
31
|
const markdownStore = useMarkdownStore()
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
<script setup lang="ts">
|
|
30
30
|
import { mdiClose } from '@quasar/extras/mdi-v7'
|
|
31
31
|
|
|
32
|
-
import { useMarkdownStore } from '
|
|
32
|
+
import { useMarkdownStore } from '@/.q-press/stores/markdown'
|
|
33
33
|
|
|
34
34
|
import MarkdownPageToc from './MarkdownPageToc.vue'
|
|
35
35
|
|
|
@@ -38,7 +38,7 @@ import { computed } from 'vue'
|
|
|
38
38
|
import { useRoute } from 'vue-router'
|
|
39
39
|
import { mdiArrowUp } from '@quasar/extras/mdi-v7'
|
|
40
40
|
|
|
41
|
-
// import { useMarkdownStore } from '
|
|
41
|
+
// import { useMarkdownStore } from '@/.q-press/stores/doc'
|
|
42
42
|
import { useScroll } from '../composables/scroll'
|
|
43
43
|
|
|
44
44
|
import MarkdownHeader from './MarkdownHeader.vue'
|
|
@@ -469,7 +469,7 @@ const x = {
|
|
|
469
469
|
| Prop name | Description |
|
|
470
470
|
| ------------ | ----------------------------------------------------------------------------------------------------------------- |
|
|
471
471
|
| `app` | Vue app instance |
|
|
472
|
-
| `router` | Instance of Vue Router from '
|
|
472
|
+
| `router` | Instance of Vue Router from '@/router/index.js' |
|
|
473
473
|
| `store` | Instance of Pinia - **store only will be passed if your project uses Pinia (you have src/stores)** |
|
|
474
474
|
| `ssrContext` | Available only on server-side, if building for SSR. [More info](/quasar-cli-vite/developing-ssr/ssr-context) |
|
|
475
475
|
| `urlPath` | The pathname (path + search) part of the URL. It also contains the hash on client-side. |
|
|
@@ -481,7 +481,7 @@ const x = {
|
|
|
481
481
|
| Prop name | Description |
|
|
482
482
|
| :----------- | :---------------------------------------------------------------------------------------------------------------- |
|
|
483
483
|
| `app` | Vue app instance |
|
|
484
|
-
| `router` | Instance of Vue Router from '
|
|
484
|
+
| `router` | Instance of Vue Router from '@/router/index.js' |
|
|
485
485
|
| `store` | Instance of Pinia - **store only will be passed if your project uses Pinia (you have src/stores)** |
|
|
486
486
|
| `ssrContext` | Available only on server-side, if building for SSR. [More info](/quasar-cli-vite/developing-ssr/ssr-context) |
|
|
487
487
|
| `urlPath` | The pathname (path + search) part of the URL. It also contains the hash on client-side. |
|
|
@@ -493,7 +493,7 @@ const x = {
|
|
|
493
493
|
| Prop name | Description |
|
|
494
494
|
| -----------: | ----------------------------------------------------------------------------------------------------------------: |
|
|
495
495
|
| `app` | Vue app instance |
|
|
496
|
-
| `router` |
|
|
496
|
+
| `router` | Instance of Vue Router from '@/router/index.js' |
|
|
497
497
|
| `store` | Instance of Pinia - **store only will be passed if your project uses Pinia (you have src/stores)** |
|
|
498
498
|
| `ssrContext` | Available only on server-side, if building for SSR. [More info](/quasar-cli-vite/developing-ssr/ssr-context) |
|
|
499
499
|
| `urlPath` | The pathname (path + search) part of the URL. It also contains the hash on client-side. |
|
|
@@ -505,7 +505,7 @@ const x = {
|
|
|
505
505
|
| Prop name | Description |
|
|
506
506
|
| :----------: | :---------------------------------------------------------------------------------------------------------------: |
|
|
507
507
|
| `app` | Vue app instance |
|
|
508
|
-
| `router` |
|
|
508
|
+
| `router` | Instance of Vue Router from '@/router/index.js' |
|
|
509
509
|
| `store` | Instance of Pinia - **store only will be passed if your project uses Pinia (you have src/stores)** |
|
|
510
510
|
| `ssrContext` | Available only on server-side, if building for SSR. [More info](/quasar-cli-vite/developing-ssr/ssr-context) |
|
|
511
511
|
| `urlPath` | The pathname (path + search) part of the URL. It also contains the hash on client-side. |
|
|
@@ -532,8 +532,8 @@ Lorem ipsum dolor sit amet, **consectetur adipiscing** elit, sed do _eiusmod_ te
|
|
|
532
532
|
Lorem ipsum dolor sit amet, **consectetur adipiscing** elit, sed do _eiusmod_ tempor incididunt ut labore et dolore magna aliqua.
|
|
533
533
|
|
|
534
534
|
<script import>
|
|
535
|
-
import MarkdownExampleApi from '
|
|
536
|
-
import MarkdownPageApi from '
|
|
535
|
+
import MarkdownExampleApi from '@/.q-press/api/components/MarkdownExample.json'
|
|
536
|
+
import MarkdownPageApi from '@/.q-press/api/components/MarkdownPage.json'
|
|
537
537
|
</script>
|
|
538
538
|
|
|
539
539
|
<MarkdownApi :api="MarkdownExampleApi" name="MarkdownExample"/>
|
|
@@ -345,8 +345,8 @@ import AvatarApi from 'quasar/dist/api/QAvatar.json'
|
|
|
345
345
|
<MarkdownApi :api="AvatarApi" name="QAvatar"/>
|
|
346
346
|
|
|
347
347
|
<script import>
|
|
348
|
-
import MarkdownExampleApi from '
|
|
349
|
-
import MarkdownPageApi from '
|
|
348
|
+
import MarkdownExampleApi from '@/.q-press/api/components/MarkdownExample.json'
|
|
349
|
+
import MarkdownPageApi from '@/.q-press/api/components/MarkdownPage.json'
|
|
350
350
|
</script>
|
|
351
351
|
|
|
352
352
|
<MarkdownApi :api="MarkdownExampleApi" name="MarkdownExample"/>
|
|
@@ -633,8 +633,8 @@ md.use(codeblocksPlugin, {
|
|
|
633
633
|
preClass: 'markdown-code', // Optional: Customize the class for the pre tag
|
|
634
634
|
codeClass: '', // Optional: Customize the class for the code tag
|
|
635
635
|
pageScripts: [
|
|
636
|
-
"import MarkdownPrerender from '
|
|
637
|
-
"import MarkdownCopyButton from '
|
|
636
|
+
"import MarkdownPrerender from '@/.q-press/components/MarkdownPrerender'", // ts file
|
|
637
|
+
"import MarkdownCopyButton from '@/.q-press/components/MarkdownCopyButton.vue'",
|
|
638
638
|
], // Optional: Include page scripts
|
|
639
639
|
langList: [
|
|
640
640
|
{ name: 'javascript', aliases: 'javascript|js' },
|
|
@@ -688,8 +688,8 @@ md.use(codeblocksPlugin, {
|
|
|
688
688
|
preClass: 'markdown-pre', // Customize the class for the pre tag
|
|
689
689
|
codeClass: 'markdown-code', // Customize the class for the code tag
|
|
690
690
|
pageScripts: [
|
|
691
|
-
"import MarkdownPrerender from '
|
|
692
|
-
"import MarkdownCopyButton from '
|
|
691
|
+
"import MarkdownPrerender from '@/.q-press/components/MarkdownPrerender'", // ts file
|
|
692
|
+
"import MarkdownCopyButton from '@/.q-press/components/MarkdownCopyButton.vue'",
|
|
693
693
|
], // Include page scripts
|
|
694
694
|
langList: [
|
|
695
695
|
{ name: 'javascript', aliases: 'javascript|js' },
|
|
@@ -83,7 +83,7 @@ The `link` plugin provides several options for customization. Here are the avail
|
|
|
83
83
|
#### pageScript
|
|
84
84
|
|
|
85
85
|
- **Type**: `string`
|
|
86
|
-
- **Default**: `'import MarkdownLink from "
|
|
86
|
+
- **Default**: `'import MarkdownLink from "@/.q-press/components/MarkdownLink.vue"'`
|
|
87
87
|
- **Description**: The script to import the custom link component.
|
|
88
88
|
|
|
89
89
|
### Example Configuration
|
|
@@ -99,7 +99,7 @@ const md = new MarkdownIt()
|
|
|
99
99
|
md.use(linkPlugin, {
|
|
100
100
|
linkTag: 'CustomLink',
|
|
101
101
|
linkToKeyword: 'href',
|
|
102
|
-
pageScript: 'import CustomLink from "
|
|
102
|
+
pageScript: 'import CustomLink from "@/components/CustomLink.vue"',
|
|
103
103
|
})
|
|
104
104
|
```
|
|
105
105
|
|
|
@@ -38,7 +38,7 @@ const md = new MarkdownIt()
|
|
|
38
38
|
md.use(linkPlugin, {
|
|
39
39
|
linkTag: 'CustomLink', // Optional: Customize the link tag
|
|
40
40
|
linkToKeyword: 'href', // Optional: Customize the link keyword
|
|
41
|
-
pageScript: 'import CustomLink from "
|
|
41
|
+
pageScript: 'import CustomLink from "@/components/CustomLink.vue"', // Optional: Add import statement
|
|
42
42
|
})
|
|
43
43
|
|
|
44
44
|
// Now you can use the Link plugin in your Markdown content
|
|
@@ -78,7 +78,7 @@ const md = new MarkdownIt()
|
|
|
78
78
|
md.use(linkPlugin, {
|
|
79
79
|
linkTag: 'CustomLink', // Optional: Customize the link tag
|
|
80
80
|
linkToKeyword: 'href', // Optional: Customize the link keyword
|
|
81
|
-
pageScript: 'import CustomLink from "
|
|
81
|
+
pageScript: 'import CustomLink from "@/components/CustomLink.vue"', // Optional: Add import statement
|
|
82
82
|
})
|
|
83
83
|
|
|
84
84
|
// Now you can use the Link plugin in your Markdown content
|
|
@@ -109,7 +109,7 @@ const md = new MarkdownIt()
|
|
|
109
109
|
md.use(linkPlugin, {
|
|
110
110
|
linkTag: 'CustomLink', // Customize the link tag
|
|
111
111
|
linkToKeyword: 'href', // Customize the link keyword
|
|
112
|
-
pageScript: 'import CustomLink from "
|
|
112
|
+
pageScript: 'import CustomLink from "@/components/CustomLink.vue"', // Add import statement
|
|
113
113
|
})
|
|
114
114
|
.use(markdownItAnchor)
|
|
115
115
|
.use(markdownItToc)
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: Shared
|
|
3
|
-
desc: Overview of the shared utilities and types
|
|
2
|
+
title: Shared Package Overview
|
|
3
|
+
desc: Overview of the shared utilities and types used by MD-Plugins packages.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
The
|
|
6
|
+
The `@md-plugins/shared` package provides utilities and types used internally by the MD-Plugins packages. It serves as a common foundation, ensuring consistency and reducing duplication across the different plugins.
|
|
7
|
+
|
|
8
|
+
::: tip
|
|
9
|
+
QPress applications do not need to install or import `@md-plugins/shared` directly. Install it only when you are building a custom Markdown-It plugin or contributing to the MD-Plugins packages themselves.
|
|
10
|
+
:::
|
|
7
11
|
|
|
8
12
|
## Key Features
|
|
9
13
|
|
|
10
14
|
- **Common Utilities**: Provides utility functions that are commonly used across multiple plugins.
|
|
11
15
|
- **Type Definitions**: Includes TypeScript type definitions to ensure type safety and consistency.
|
|
12
16
|
- **Helper Functions**: Offers helper functions to simplify common tasks and operations.
|
|
13
|
-
- **Reusable
|
|
17
|
+
- **Reusable Helpers**: Contains shared helpers that can be leveraged by other MD-Plugins packages.
|
|
14
18
|
|
|
15
19
|
## Utilities
|
|
16
20
|
|
|
17
|
-
The
|
|
21
|
+
The shared package includes a variety of utility functions that can be used to perform common tasks. Some of the key utilities include:
|
|
18
22
|
|
|
19
23
|
- **String Manipulation**: Functions for manipulating and formatting strings.
|
|
20
24
|
- **Array Operations**: Functions for performing common array operations.
|
|
@@ -23,7 +27,7 @@ The `shared` plugin includes a variety of utility functions that can be used to
|
|
|
23
27
|
|
|
24
28
|
## Type Definitions
|
|
25
29
|
|
|
26
|
-
The
|
|
30
|
+
The shared package provides TypeScript type definitions that are used across the MD-Plugins project. These type definitions help ensure type safety and consistency. Some of the key type definitions include:
|
|
27
31
|
|
|
28
32
|
- **MarkdownItEnv**: Defines the structure of the environment object used by MD-Plugins plugins.
|
|
29
33
|
- **PluginOptions**: Defines the structure of the options object passed to plugins.
|
|
@@ -179,7 +183,7 @@ export {
|
|
|
179
183
|
|
|
180
184
|
## Helper Functions
|
|
181
185
|
|
|
182
|
-
The
|
|
186
|
+
The shared package includes a variety of helper functions that simplify common tasks and operations. Some of the key helper functions include:
|
|
183
187
|
|
|
184
188
|
- **resolveTitleFromToken**: Extracts the title from a Markdown token.
|
|
185
189
|
- **parseFrontmatter**: Parses frontmatter content from a Markdown file.
|
|
@@ -190,6 +194,6 @@ The `shared` plugin includes a variety of helper functions that simplify common
|
|
|
190
194
|
|
|
191
195
|
## Conclusion
|
|
192
196
|
|
|
193
|
-
The
|
|
197
|
+
The shared package is an essential internal part of the MD-Plugins project, providing common utilities, type definitions, and helper functions. If you are building custom plugins, you can use it to stay aligned with the same types and helpers used by the official MD-Plugins packages.
|
|
194
198
|
|
|
195
199
|
Happy coding!
|
|
@@ -8,33 +8,33 @@ Q-Press has a lot of components that can be used in your app. Under the hood, th
|
|
|
8
8
|
## Components
|
|
9
9
|
|
|
10
10
|
<script import>
|
|
11
|
-
import DarkModeToggleApi from '
|
|
12
|
-
import MarkdownApiApi from '
|
|
13
|
-
import MarkdownCardLinkApi from '
|
|
14
|
-
import MarkdownCardTitleApi from '
|
|
15
|
-
import MarkdownCodeApi from '
|
|
16
|
-
import MarkdownCodepenApi from '
|
|
11
|
+
import DarkModeToggleApi from '@/.q-press/api/components/DarkModeToggle.json'
|
|
12
|
+
import MarkdownApiApi from '@/.q-press/api/components/MarkdownApi.json'
|
|
13
|
+
import MarkdownCardLinkApi from '@/.q-press/api/components/MarkdownCardLink.json'
|
|
14
|
+
import MarkdownCardTitleApi from '@/.q-press/api/components/MarkdownCardTitle.json'
|
|
15
|
+
import MarkdownCodeApi from '@/.q-press/api/components/MarkdownCode.json'
|
|
16
|
+
import MarkdownCodepenApi from '@/.q-press/api/components/MarkdownCodepen.json'
|
|
17
17
|
|
|
18
|
-
import MarkdownCodePrismApi from '
|
|
19
|
-
import MarkdownCopyButtonApi from '
|
|
20
|
-
import MarkdownDrawerSidebarApi from '
|
|
21
|
-
import MarkdownDrawerTocApi from '
|
|
18
|
+
import MarkdownCodePrismApi from '@/.q-press/api/components/MarkdownCodePrism.json'
|
|
19
|
+
import MarkdownCopyButtonApi from '@/.q-press/api/components/MarkdownCopyButton.json'
|
|
20
|
+
import MarkdownDrawerSidebarApi from '@/.q-press/api/components/MarkdownDrawerSidebar.json'
|
|
21
|
+
import MarkdownDrawerTocApi from '@/.q-press/api/components/MarkdownDrawerToc.json'
|
|
22
22
|
|
|
23
|
-
import MarkdownExampleApi from '
|
|
24
|
-
import MarkdownHeaderApi from '
|
|
25
|
-
import MarkdownHeaderIconLinksApi from '
|
|
26
|
-
import MarkdownHeaderMenuApi from '
|
|
27
|
-
import MarkdownHeaderTextLinksApi from '
|
|
23
|
+
import MarkdownExampleApi from '@/.q-press/api/components/MarkdownExample.json'
|
|
24
|
+
import MarkdownHeaderApi from '@/.q-press/api/components/MarkdownHeader.json'
|
|
25
|
+
import MarkdownHeaderIconLinksApi from '@/.q-press/api/components/MarkdownHeaderIconLinks.json'
|
|
26
|
+
import MarkdownHeaderMenuApi from '@/.q-press/api/components/MarkdownHeaderMenu.json'
|
|
27
|
+
import MarkdownHeaderTextLinksApi from '@/.q-press/api/components/MarkdownHeaderTextLinks.json'
|
|
28
28
|
|
|
29
|
-
import MarkdownLayoutApi from '
|
|
30
|
-
import MarkdownLinkApi from '
|
|
31
|
-
import MarkdownPageApi from '
|
|
32
|
-
import MarkdownPageFooterApi from '
|
|
33
|
-
import MarkdownPageSidebarApi from '
|
|
34
|
-
import MarkdownPageTocApi from '
|
|
29
|
+
import MarkdownLayoutApi from '@/.q-press/api/components/MarkdownLayout.json'
|
|
30
|
+
import MarkdownLinkApi from '@/.q-press/api/components/MarkdownLink.json'
|
|
31
|
+
import MarkdownPageApi from '@/.q-press/api/components/MarkdownPage.json'
|
|
32
|
+
import MarkdownPageFooterApi from '@/.q-press/api/components/MarkdownPageFooter.json'
|
|
33
|
+
import MarkdownPageSidebarApi from '@/.q-press/api/components/MarkdownPageSidebar.json'
|
|
34
|
+
import MarkdownPageTocApi from '@/.q-press/api/components/MarkdownPageToc.json'
|
|
35
35
|
|
|
36
|
-
import MarkdownTreeApi from '
|
|
37
|
-
import MarkdownPrerenderApi from '
|
|
36
|
+
import MarkdownTreeApi from '@/.q-press/api/components/MarkdownTree.json'
|
|
37
|
+
import MarkdownPrerenderApi from '@/.q-press/api/components/MarkdownPrerender.json'
|
|
38
38
|
|
|
39
39
|
</script>
|
|
40
40
|
|
|
@@ -125,12 +125,12 @@ export default defineConfig(async (ctx) => {
|
|
|
125
125
|
|
|
126
126
|
```ts [maxheight=400px]
|
|
127
127
|
import type { RouteRecordRaw } from 'vue-router'
|
|
128
|
-
import mdPageList from '
|
|
128
|
+
import mdPageList from '@/markdown/listing'
|
|
129
129
|
|
|
130
130
|
const routes = [
|
|
131
131
|
{
|
|
132
132
|
path: '/',
|
|
133
|
-
component: () => import('
|
|
133
|
+
component: () => import('@/.q-press/layouts/MarkdownLayout.vue'),
|
|
134
134
|
children: [
|
|
135
135
|
// Include the Landing Page route first
|
|
136
136
|
...Object.entries(mdPageList)
|
|
@@ -169,7 +169,7 @@ const routes = [
|
|
|
169
169
|
// but you can also remove it
|
|
170
170
|
{
|
|
171
171
|
path: '/:catchAll(.*)*',
|
|
172
|
-
component: () => import('pages/ErrorNotFound.vue'),
|
|
172
|
+
component: () => import('@/pages/ErrorNotFound.vue'),
|
|
173
173
|
},
|
|
174
174
|
] as RouteRecordRaw[]
|
|
175
175
|
|
|
@@ -186,7 +186,7 @@ Update your `App.vue`:
|
|
|
186
186
|
</template>
|
|
187
187
|
|
|
188
188
|
<script setup lang="ts">
|
|
189
|
-
import { useDark } from '
|
|
189
|
+
import { useDark } from '@/.q-press/composables/dark'
|
|
190
190
|
const { initDark } = useDark()
|
|
191
191
|
initDark()
|
|
192
192
|
</script>
|
|
@@ -206,7 +206,7 @@ Update your `App.vue`:
|
|
|
206
206
|
<script setup lang="ts">
|
|
207
207
|
// don't forget to add the Quasar 'Meta' plugin into your quasar.config file!
|
|
208
208
|
import { useMeta } from 'quasar'
|
|
209
|
-
import getMeta from '
|
|
209
|
+
import getMeta from '@/.q-press/assets/get-meta'
|
|
210
210
|
|
|
211
211
|
// You can use the `getMeta` function to get the meta tags for your page and provide default values
|
|
212
212
|
useMeta({
|
|
@@ -35,7 +35,7 @@ The `viteMdPlugin` is built on top of the following plugins:
|
|
|
35
35
|
| `@md-plugins/md-plugin-title` | Extracts the first header in Markdown as the page title. | [README](packages/md-plugin-title/README.md) | [Docs](/md-plugins/title/overview) |
|
|
36
36
|
| `@md-plugins/md-plugin-frontmatter` | Extracts and processes frontmatter content from Markdown files. | [README](packages/md-plugin-frontmatter/README.md) | [Docs](/md-plugins/frontmatter/overview) |
|
|
37
37
|
| `@md-plugins/md-plugin-containers` | Adds custom containers for callouts, warnings, and more. | [README](packages/md-plugin-containers/README.md) | [Docs](/md-plugins/containers/overview) |
|
|
38
|
-
| `@md-plugins/shared` |
|
|
38
|
+
| `@md-plugins/shared` | Internal shared utilities and types used by the bundled plugins. | [README](packages/shared/README.md) | [Docs](/md-plugins/shared/overview) |
|
|
39
39
|
|
|
40
40
|
## Installation
|
|
41
41
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fabGithub, fabXTwitter } from '@quasar/extras/fontawesome-v7'
|
|
2
|
-
import { slugify } from '@md-plugins/shared'
|
|
3
2
|
import { version, productName } from '../../package.json'
|
|
3
|
+
import { slugify } from '../.q-press/components/markdown-utils'
|
|
4
4
|
|
|
5
5
|
export interface SocialLink {
|
|
6
6
|
name: string
|
|
@@ -15,9 +15,8 @@
|
|
|
15
15
|
import { Quasar } from 'quasar'
|
|
16
16
|
import { ref, reactive, computed, nextTick } from 'vue'
|
|
17
17
|
|
|
18
|
-
import { slugify } from '@md-plugins/shared'
|
|
19
|
-
|
|
20
18
|
import siteConfig from '../../siteConfig'
|
|
19
|
+
import { slugify } from './markdown-utils'
|
|
21
20
|
|
|
22
21
|
type CodepenParts = {
|
|
23
22
|
Template?: string
|
|
@@ -41,6 +40,26 @@ const defaultJsResources = [
|
|
|
41
40
|
`https://cdn.jsdelivr.net/npm/quasar@${Quasar.version}/dist/quasar.umd.prod.js`,
|
|
42
41
|
]
|
|
43
42
|
|
|
43
|
+
function getAbsolutePublicUrl(path: string) {
|
|
44
|
+
const normalizedPath = path.startsWith('/') ? path : `/${path}`
|
|
45
|
+
|
|
46
|
+
return typeof location === 'undefined' ? normalizedPath : `${location.origin}${normalizedPath}`
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function rewriteRootRelativeUrls(content: string) {
|
|
50
|
+
return content
|
|
51
|
+
.replace(
|
|
52
|
+
/\b(src|href|poster)=("|')\/(?!\/)([^"']*)\2/g,
|
|
53
|
+
(_match: string, attr: string, quote: string, path: string) =>
|
|
54
|
+
`${attr}=${quote}${getAbsolutePublicUrl(path)}${quote}`,
|
|
55
|
+
)
|
|
56
|
+
.replace(
|
|
57
|
+
/url\(\s*(["']?)\/(?!\/)([^"')]+)\1\s*\)/g,
|
|
58
|
+
(_match: string, quote: string, path: string) =>
|
|
59
|
+
`url(${quote}${getAbsolutePublicUrl(path)}${quote})`,
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
44
63
|
function indent(code: string, spaces = 2) {
|
|
45
64
|
const padding = ' '.repeat(spaces)
|
|
46
65
|
return code
|
|
@@ -271,7 +290,7 @@ const jsResources = computed(() => {
|
|
|
271
290
|
})
|
|
272
291
|
|
|
273
292
|
const css = computed(() => {
|
|
274
|
-
return (def.parts.Style || '').replace(/(<style.*?>|<\/style>)/g, '').trim()
|
|
293
|
+
return rewriteRootRelativeUrls((def.parts.Style || '').replace(/(<style.*?>|<\/style>)/g, '').trim())
|
|
275
294
|
})
|
|
276
295
|
|
|
277
296
|
const cssPreprocessor = computed(() => {
|
|
@@ -297,7 +316,7 @@ const jsPreProcessor = computed(() => {
|
|
|
297
316
|
})
|
|
298
317
|
|
|
299
318
|
const html = computed(() => {
|
|
300
|
-
|
|
319
|
+
const content = (def.parts.Template || '')
|
|
301
320
|
.replace(/(<template>|<\/template>$)/g, '')
|
|
302
321
|
.replace(/\n/g, '\n ')
|
|
303
322
|
.replace(/([\w]+=")([^"]*?)(")/g, function (match, p1, p2, p3) {
|
|
@@ -331,6 +350,8 @@ const html = computed(() => {
|
|
|
331
350
|
.replace(/___TEMP_REPLACEMENT___/g, '>')
|
|
332
351
|
.replace(/^\s{2}/gm, '')
|
|
333
352
|
.trim()
|
|
353
|
+
|
|
354
|
+
return rewriteRootRelativeUrls(content)
|
|
334
355
|
})
|
|
335
356
|
|
|
336
357
|
const editors = computed(() => {
|
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
import { Notify } from 'quasar'
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
const andRE = /&/g
|
|
4
|
+
const rCombining = /[\u0300-\u036F]/g
|
|
5
|
+
// oxlint-disable-next-line no-control-regex
|
|
6
|
+
const rControl = /[\u0000-\u001f]/g
|
|
7
|
+
const rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'“”‘’<>,.?/]+/g
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Default slugification function used by qPress client helpers.
|
|
11
|
+
*/
|
|
12
|
+
export const slugify = (str: string): string =>
|
|
13
|
+
str
|
|
14
|
+
.trim()
|
|
15
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
16
|
+
.replace(/[\s_]+/g, '-')
|
|
17
|
+
.toLowerCase()
|
|
18
|
+
.normalize('NFKD')
|
|
19
|
+
.replace(rCombining, '')
|
|
20
|
+
.replace(andRE, '-and-')
|
|
21
|
+
.replace(rControl, '-')
|
|
22
|
+
.replace(rSpecial, '-')
|
|
23
|
+
.replace(/[^a-z0-9-]+/g, '')
|
|
24
|
+
.replace(/([a-z])(\d)/g, '$1-$2')
|
|
25
|
+
.replace(/(\d)([a-z])/g, '$1-$2')
|
|
26
|
+
.replace(/-{2,}/g, '-')
|
|
27
|
+
.replace(/(^-|-$)/g, '')
|
|
28
|
+
.replace(/^(\d)/, '_$1')
|
|
3
29
|
|
|
4
30
|
/**
|
|
5
31
|
* Fallback function to copy text to clipboard when the Clipboard API is not available.
|
|
@@ -101,5 +127,3 @@ export function copyHeading(id: string): void {
|
|
|
101
127
|
timeout: 2000,
|
|
102
128
|
})
|
|
103
129
|
}
|
|
104
|
-
|
|
105
|
-
export { slugify }
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<script setup lang="ts">
|
|
26
26
|
import { mdiClose } from '@quasar/extras/mdi-v7'
|
|
27
27
|
|
|
28
|
-
import { useMarkdownStore } from '
|
|
28
|
+
import { useMarkdownStore } from '@/.q-press/stores/markdown'
|
|
29
29
|
import MarkdownPageSidebar from './MarkdownPageSidebar'
|
|
30
30
|
|
|
31
31
|
const markdownStore = useMarkdownStore()
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
<script setup lang="ts">
|
|
30
30
|
import { mdiClose } from '@quasar/extras/mdi-v7'
|
|
31
31
|
|
|
32
|
-
import { useMarkdownStore } from '
|
|
32
|
+
import { useMarkdownStore } from '@/.q-press/stores/markdown'
|
|
33
33
|
|
|
34
34
|
import MarkdownPageToc from './MarkdownPageToc.vue'
|
|
35
35
|
|
|
@@ -38,7 +38,7 @@ import { computed } from 'vue'
|
|
|
38
38
|
import { useRoute } from 'vue-router'
|
|
39
39
|
import { mdiArrowUp } from '@quasar/extras/mdi-v7'
|
|
40
40
|
|
|
41
|
-
// import { useMarkdownStore } from '
|
|
41
|
+
// import { useMarkdownStore } from '@/.q-press/stores/doc'
|
|
42
42
|
import { useScroll } from '../composables/scroll'
|
|
43
43
|
|
|
44
44
|
import MarkdownHeader from './MarkdownHeader.vue'
|