Skip to content

Commit 43fa9ec

Browse files
committed
feat: Plug-in system for one-offs #7
1 parent 28a5657 commit 43fa9ec

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

demo/src/markdown/markdown.vmd

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
title: QMarkdown Docs
33
desc: This is the documentation for QMarkdown
44
---
5+
56
<template>
67
<div class="q-pa-md q-gutter-sm q-markdown">
78

@@ -94,6 +95,7 @@ The recommended way, would be to import the markdown to be used so that it doesn
9495
QMarkdown comes with a Webpack loader for importing markdown files directly into your code.
9596

9697
In your JavaScript:
98+
9799
```js
98100
import markdown from '../markdown/calendar.md'
99101

@@ -107,16 +109,19 @@ export default {
107109
},
108110
...
109111
```
112+
110113
And, in your HTML:
111114
```html
112115
<q-markdown :src="markdown" />
113116
```
117+
114118
## Setting up Table of Contents
115119
You enable a TOC by setting `:toc="true"` on the `q-markdown` component. The data in the TOC is based on HTML Headings (H1-H6). You can change the number of headings that you are interested in by using the `toc-start` and `toc-end` properties.
116120

117121
To get the data for the TOC, you must use the `@data` event.
118122

119123
HTML
124+
120125
```html
121126
<q-markdown :src="markdown" toc @data="onToc" />
122127
```
@@ -131,6 +136,7 @@ methods: {
131136
```
132137

133138
The TOC data looks like this:
139+
134140
```
135141
[
136142
{id: 'h2-Heading', title: 'h2 Heading', level: 2, children: []},
@@ -141,11 +147,13 @@ The TOC data looks like this:
141147
If you desire a hierarchical tree of data instead, do the following:
142148

143149
HTML
150+
144151
```html
145152
<q-markdown ref="markdown" :src="markdown" toc @data="onToc" />
146153
```
147154

148155
JavaScript:
156+
149157
```js
150158
methods: {
151159
onToc (toc) {
@@ -155,6 +163,7 @@ methods: {
155163
```
156164

157165
The TOC data will be transformed to the following:
166+
158167
```
159168
[
160169
{id: 'h2-Heading', title: 'h2 Heading', level: 2, children: [
@@ -170,6 +179,7 @@ You are able to mix Vue (SFC: single-file component) and Markdown together. This
170179
The minimal viable `.vmd` file must contain a `<template>` section. All other sections are optional.
171180

172181
Example (from the top of this file):
182+
173183
```html
174184
<template>
175185
<div class="q-pa-md q-gutter-sm q-markdown">
@@ -183,6 +193,7 @@ QMarkdown is a [Quasar App Extension](https://v1.quasar.dev/app-extensions/intro
183193
... // the rest of the markdown
184194
</template>
185195
```
196+
186197
As you may have noticed, your HTML code should add the `q-markdown` class to the wrapper html in order to get all proper syntax highlighting.
187198

188199
Now, as far as getting it to be displayed on your page, do the following in your `<script>` section:
@@ -218,6 +229,7 @@ If you would like to generate a TOC (Table of Contents) derived from the header
218229
}
219230
},
220231
```
232+
221233
The Vue+Markdown (`.vmd`) loader will replace the `tocData: [ ]` (extra space in square brackets added to avoid this feature in the docs) if found and add the TOC data.
222234

223235
::: warning
@@ -267,6 +279,7 @@ title: QMarkdown Docs
267279
desc: This is the documentation for QMarkdown
268280
---
269281
```
282+
270283
This will be converted to:
271284

272285
```js
@@ -278,7 +291,7 @@ This will be converted to:
278291

279292
This is injected into your Vue data by having the following:
280293

281-
```
294+
```js
282295
data () {
283296
return {
284297
// eslint-disable-next-line
@@ -294,6 +307,7 @@ Notice the commented line `eslint-disable-next-line`? The data added is not form
294307
:::
295308

296309
Finally, you can use the Front-Matter data like this:
310+
297311
```js
298312
mounted () {
299313
document.title = this.frontMatter.title
@@ -308,7 +322,9 @@ import getTagParts from '@quasar/quasar-app-extension-qmarkdown/src/lib/getTagPa
308322
// or
309323
const getTagParts = require('@quasar/quasar-app-extension-qmarkdown/src/lib/getTagParts').default
310324
```
325+
311326
And then, you can use it like this:
327+
312328
```
313329
mounted () {
314330
// eslint-disable-next-line import/no-webpack-loader-syntax
@@ -319,6 +335,7 @@ And then, you can use it like this:
319335
console.log('css', results.css)
320336
},
321337
```
338+
322339
This makes use of the `raw-loader` Webpack loader. The exclamations are needed to tell Webpack to overload the default loader.
323340

324341
::: tip
@@ -327,6 +344,38 @@ This makes use of the `raw-loader` Webpack loader. The exclamations are needed t
327344

328345
Now, you will have access to the tag parts of the Vue file.
329346

347+
# Extending Markdown-it!
348+
You can use the `extend` property to extend the Markdown-it! markdown processor. The extend function takes a single argument of the md (markdown) instance.
349+
350+
Now, you can extend QMarkdown with either your own code or Markdown-it! [plugins](https://www.npmjs.com/search?q=keywords:markdown-it-plugin). Please read the Markdown-It [documentation](https://github.com/markdown-it/markdown-it#readme) on how to do this.
351+
352+
Syntax:
353+
354+
```html
355+
<q-markdown :extend="extendMarkdown" />
356+
```
357+
358+
```js
359+
methods: {
360+
// to extend links
361+
extendMarkdown (md) {
362+
md.renderer.rules.link_open = (tokens, idx, options, env, self) => {
363+
const token = tokens[idx]
364+
365+
const hrefIndex = token.attrIndex('href')
366+
if (token.attrs[hrefIndex][1][0] === '/') {
367+
token.attrSet('class', 'q-markdown--link q-markdown--link-local')
368+
} else {
369+
token.attrSet('class', 'q-markdown--link q-markdown--link-external')
370+
token.attrSet('target', '_blank')
371+
}
372+
373+
return self.renderToken(tokens, idx, options)
374+
}
375+
}
376+
}
377+
```
378+
330379
# API
331380

332381
## Vue Properties
@@ -357,6 +406,7 @@ Now, you will have access to the tag parts of the Vue file.
357406
| task-lists-enable | Boolean | set to true to enable task lists checkboxes (not read-only) |
358407
| task-lists-label | Boolean | to wrap the rendered list items in a label element for UX purposes |
359408
| task-lists-enable-after | Boolean | to add the label after the checkbox |
409+
| extend | Function | extend the markdown-it! processor |
360410
| content-class | [String, Object, Array] | Class definitions to be attributed to the markdown |
361411
| content-style | [String, Object, Array] | Style definitions to be attributed to the markdown |
362412

@@ -366,13 +416,15 @@ Now, you will have access to the tag parts of the Vue file.
366416
| data | If the `toc` property is set to `true`, this event will occur containing any TOC data, if there is any. This is an array of flat data |
367417

368418
Given markdown that looks like this:
419+
369420
```
370421
## h2 Heading
371422

372423
### h3 Heading
373424
```
374425

375426
The TOC data looks like this:
427+
376428
```
377429
[
378430
{id: 'h2-Heading', title: 'h2 Heading', level: 2, children: []},
@@ -386,6 +438,7 @@ The TOC data looks like this:
386438
| makeTree | Pass into this function the results from the @data to have the data array transformed into a hieracrhial tree. |
387439

388440
The TOC data will be transformed to the following:
441+
389442
```
390443
[
391444
{id: 'h2-Heading', title: 'h2 Heading', level: 2, children: [
@@ -403,7 +456,7 @@ The TOC data will be transformed to the following:
403456
If you appreciate the work that went into this App Extension, please consider [donating to Quasar](https://donate.quasar.dev).
404457

405458
---
406-
This page created with [QMarkdown](https://quasarframework.github.io/app-extension-qmarkdown/demo/dist/spa/#/images).
459+
This page created with [QMarkdown](https://quasarframework.github.io/app-extension-qmarkdown/demo/dist/spa/#/images). It is in the `vmd` format. You can view it's source [here](https://github.com/quasarframework/app-extension-qmarkdown/blob/dev/demo/src/markdown/markdown.vmd)
407460

408461
</div>
409462
</template>

src/component/QMarkdown.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ export default Vue.extend({
8888
taskListsLabel: Boolean,
8989
// to add the label after the checkbox
9090
taskListsLabelAfter: Boolean,
91+
// extend markdown-it!
92+
extend: Function,
9193
contentStyle: [String, Object, Array],
9294
contentClass: [String, Object, Array]
9395
},
@@ -110,6 +112,10 @@ export default Vue.extend({
110112
return val === void 0 || val === false
111113
},
112114

115+
__isFunction (f) {
116+
return f && {}.toString.call(f) === '[object Function]'
117+
},
118+
113119
makeTree (list) {
114120
let tree = []
115121
let root = null
@@ -219,6 +225,10 @@ export default Vue.extend({
219225
md.disable(disabled)
220226
}
221227

228+
if (this.__isFunction(this.extend)) {
229+
this.extend(md)
230+
}
231+
222232
const rendered = md.render(markdown)
223233

224234
if (this.toc && tocData.length > 0) {

0 commit comments

Comments
 (0)