@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.
Files changed (42) hide show
  1. package/README.md +12 -5
  2. package/dist/templates/init/src/_q-press/components/MarkdownCodepen.vue +25 -4
  3. package/dist/templates/init/src/_q-press/components/markdown-utils.ts +27 -3
  4. package/dist/templates/init/src/_q-press/layouts/MarkdownDrawerSidebar.vue +1 -1
  5. package/dist/templates/init/src/_q-press/layouts/MarkdownDrawerToc.vue +1 -1
  6. package/dist/templates/init/src/_q-press/layouts/MarkdownLayout.vue +1 -1
  7. package/dist/templates/init/src/markdown/__elements.md +6 -6
  8. package/dist/templates/init/src/markdown/__elements2.md +2 -2
  9. package/dist/templates/init/src/markdown/md-plugins/codeblocks/overview.md +4 -4
  10. package/dist/templates/init/src/markdown/md-plugins/link/advanced.md +2 -2
  11. package/dist/templates/init/src/markdown/md-plugins/link/overview.md +3 -3
  12. package/dist/templates/init/src/markdown/md-plugins/shared/overview.md +12 -8
  13. package/dist/templates/init/src/markdown/quasar-app-extensions/qpress/components.md +23 -23
  14. package/dist/templates/init/src/markdown/quasar-app-extensions/qpress/overview.md +5 -5
  15. package/dist/templates/init/src/markdown/vite-plugins/vite-md-plugin/overview.md +1 -1
  16. package/dist/templates/init/src/siteConfig/index.ts +1 -1
  17. package/dist/templates/update/src/_q-press/components/MarkdownCodepen.vue +25 -4
  18. package/dist/templates/update/src/_q-press/components/markdown-utils.ts +27 -3
  19. package/dist/templates/update/src/_q-press/layouts/MarkdownDrawerSidebar.vue +1 -1
  20. package/dist/templates/update/src/_q-press/layouts/MarkdownDrawerToc.vue +1 -1
  21. package/dist/templates/update/src/_q-press/layouts/MarkdownLayout.vue +1 -1
  22. package/package.json +14 -15
  23. package/src/templates/init/src/_q-press/components/MarkdownCodepen.vue +25 -4
  24. package/src/templates/init/src/_q-press/components/markdown-utils.ts +27 -3
  25. package/src/templates/init/src/_q-press/layouts/MarkdownDrawerSidebar.vue +1 -1
  26. package/src/templates/init/src/_q-press/layouts/MarkdownDrawerToc.vue +1 -1
  27. package/src/templates/init/src/_q-press/layouts/MarkdownLayout.vue +1 -1
  28. package/src/templates/init/src/markdown/__elements.md +6 -6
  29. package/src/templates/init/src/markdown/__elements2.md +2 -2
  30. package/src/templates/init/src/markdown/md-plugins/codeblocks/overview.md +4 -4
  31. package/src/templates/init/src/markdown/md-plugins/link/advanced.md +2 -2
  32. package/src/templates/init/src/markdown/md-plugins/link/overview.md +3 -3
  33. package/src/templates/init/src/markdown/md-plugins/shared/overview.md +12 -8
  34. package/src/templates/init/src/markdown/quasar-app-extensions/qpress/components.md +23 -23
  35. package/src/templates/init/src/markdown/quasar-app-extensions/qpress/overview.md +5 -5
  36. package/src/templates/init/src/markdown/vite-plugins/vite-md-plugin/overview.md +1 -1
  37. package/src/templates/init/src/siteConfig/index.ts +1 -1
  38. package/src/templates/update/src/_q-press/components/MarkdownCodepen.vue +25 -4
  39. package/src/templates/update/src/_q-press/components/markdown-utils.ts +27 -3
  40. package/src/templates/update/src/_q-press/layouts/MarkdownDrawerSidebar.vue +1 -1
  41. package/src/templates/update/src/_q-press/layouts/MarkdownDrawerToc.vue +1 -1
  42. 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.12`.
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 'src/markdown/listing'
95
+ import mdPageList from '@/markdown/listing'
96
96
  const routes = [
97
97
  {
98
98
  path: '/',
99
- component: () => import('src/.q-press/layouts/MarkdownLayout.vue'),
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 'src/.q-press/composables/dark'
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
- return (def.parts.Template || '')
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
- import { slugify } from '@md-plugins/shared'
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 'src/.q-press/stores/markdown'
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 'src/.q-press/stores/markdown'
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 'src/.q-press/stores/doc'
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 'src/router/index.js' |
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 'src/router/index.js' |
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` | Instance of Vue Router from 'src/router/index.js' |
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` | Instance of Vue Router from 'src/router/index.js' |
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 'src/.q-press/api/components/MarkdownExample.json'
536
- import MarkdownPageApi from 'src/.q-press/api/components/MarkdownPage.json'
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 'src/.q-press/api/components/MarkdownExample.json'
349
- import MarkdownPageApi from 'src/.q-press/api/components/MarkdownPage.json'
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 'src/.q-press/components/MarkdownPrerender'", // ts file
637
- "import MarkdownCopyButton from 'src/.q-press/components/MarkdownCopyButton.vue'",
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 'src/.q-press/components/MarkdownPrerender'", // ts file
692
- "import MarkdownCopyButton from 'src/.q-press/components/MarkdownCopyButton.vue'",
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 "src/.q-press/components/MarkdownLink.vue"'`
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 "src/components/CustomLink.vue"',
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 "src/components/CustomLink.vue"', // Optional: Add import statement
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 "src/components/CustomLink.vue"', // Optional: Add import statement
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 "src/components/CustomLink.vue"', // Add import statement
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 Plugin Overview
3
- desc: Overview of the shared utilities and types for MD-Plugins plugins.
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 `shared` plugin provides a set of utilities and types that are used across various MD-Plugins plugins. It serves as a common foundation, ensuring consistency and reducing duplication of code across the different plugins.
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 Components**: Contains reusable components that can be leveraged by other plugins.
17
+ - **Reusable Helpers**: Contains shared helpers that can be leveraged by other MD-Plugins packages.
14
18
 
15
19
  ## Utilities
16
20
 
17
- The `shared` plugin includes a variety of utility functions that can be used to perform common tasks. Some of the key utilities include:
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 `shared` plugin 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:
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 `shared` plugin includes a variety of helper functions that simplify common tasks and operations. Some of the key helper functions include:
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 `shared` plugin is an essential part of the MD-Plugins project, providing common utilities, type definitions, helper functions, and reusable components. By leveraging the `shared` plugin, you can ensure consistency and reduce duplication of code across your plugins.
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 'src/.q-press/api/components/DarkModeToggle.json'
12
- import MarkdownApiApi from 'src/.q-press/api/components/MarkdownApi.json'
13
- import MarkdownCardLinkApi from 'src/.q-press/api/components/MarkdownCardLink.json'
14
- import MarkdownCardTitleApi from 'src/.q-press/api/components/MarkdownCardTitle.json'
15
- import MarkdownCodeApi from 'src/.q-press/api/components/MarkdownCode.json'
16
- import MarkdownCodepenApi from 'src/.q-press/api/components/MarkdownCodepen.json'
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 'src/.q-press/api/components/MarkdownCodePrism.json'
19
- import MarkdownCopyButtonApi from 'src/.q-press/api/components/MarkdownCopyButton.json'
20
- import MarkdownDrawerSidebarApi from 'src/.q-press/api/components/MarkdownDrawerSidebar.json'
21
- import MarkdownDrawerTocApi from 'src/.q-press/api/components/MarkdownDrawerToc.json'
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 'src/.q-press/api/components/MarkdownExample.json'
24
- import MarkdownHeaderApi from 'src/.q-press/api/components/MarkdownHeader.json'
25
- import MarkdownHeaderIconLinksApi from 'src/.q-press/api/components/MarkdownHeaderIconLinks.json'
26
- import MarkdownHeaderMenuApi from 'src/.q-press/api/components/MarkdownHeaderMenu.json'
27
- import MarkdownHeaderTextLinksApi from 'src/.q-press/api/components/MarkdownHeaderTextLinks.json'
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 'src/.q-press/api/components/MarkdownLayout.json'
30
- import MarkdownLinkApi from 'src/.q-press/api/components/MarkdownLink.json'
31
- import MarkdownPageApi from 'src/.q-press/api/components/MarkdownPage.json'
32
- import MarkdownPageFooterApi from 'src/.q-press/api/components/MarkdownPageFooter.json'
33
- import MarkdownPageSidebarApi from 'src/.q-press/api/components/MarkdownPageSidebar.json'
34
- import MarkdownPageTocApi from 'src/.q-press/api/components/MarkdownPageToc.json'
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 'src/.q-press/api/components/MarkdownTree.json'
37
- import MarkdownPrerenderApi from 'src/.q-press/api/components/MarkdownPrerender.json'
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 'src/markdown/listing'
128
+ import mdPageList from '@/markdown/listing'
129
129
 
130
130
  const routes = [
131
131
  {
132
132
  path: '/',
133
- component: () => import('src/.q-press/layouts/MarkdownLayout.vue'),
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 'src/.q-press/composables/dark'
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 'src/.q-press/assets/get-meta'
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` | Shared utilities and types for the plugins. | [README](packages/shared/README.md) | [Docs](/md-plugins/shared/overview) |
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
- return (def.parts.Template || '')
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
- import { slugify } from '@md-plugins/shared'
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 'src/.q-press/stores/markdown'
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 'src/.q-press/stores/markdown'
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 'src/.q-press/stores/doc'
41
+ // import { useMarkdownStore } from '@/.q-press/stores/doc'
42
42
  import { useScroll } from '../composables/scroll'
43
43
 
44
44
  import MarkdownHeader from './MarkdownHeader.vue'