Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

markduckjs

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

markduckjs - npm Package Compare versions

Comparing version 0.0.5 to 0.0.6

lib/rehype-vue/index.d.ts

16

CHANGELOG.md

@@ -0,1 +1,17 @@

## [0.0.6](https://github.com/ymmooot/markduck/compare/v0.0.5...v0.0.6) (2019-12-21)
* make remark plugin to convert mdast to vue (#10) ([efdaf48](https://github.com/ymmooot/markduck/commit/efdaf483d277d718c9f3825515535955cdd3e524)), closes [#10](https://github.com/ymmooot/markduck/issues/10)
### BREAKING CHANGES
* 🧨 change options interface
* refactor: remove mdast-util-to-hast
* docs: update readme
## [0.0.5](https://github.com/ymmooot/markduck/compare/v0.0.4...v0.0.5) (2019-12-21)

@@ -2,0 +18,0 @@

21

lib/convert.d.ts

@@ -1,17 +0,12 @@

import { VueConstructor, CreateElement, VNode as VueVNode } from 'vue';
import { CreateElement } from 'vue';
import { Plugin, Settings } from 'unified';
import { VNode } from 'virtual-dom';
declare type ComponentRegisterFunc = (node: VNode, parentNode?: VNode) => VueConstructor<Vue> | undefined;
declare type ComponentRegisterOption = {
[keyof: string]: VueConstructor<Vue> | ComponentRegisterFunc;
};
declare type UnifiedPlugin = {
plugin: Plugin;
config: Settings;
} | Plugin;
import { ComponentRegisterOption } from './rehype-vue';
declare type PluginOption = Plugin | [Plugin, Settings];
export declare type Option = {
components: ComponentRegisterOption;
remarkPlugins: UnifiedPlugin[];
components?: ComponentRegisterOption;
sanitizeScheme?: object;
remarkPlugins?: PluginOption[];
rehypePlugins?: PluginOption[];
};
declare const convert: (createElement: CreateElement, markdown: string, option: Option) => (string | VueVNode)[];
declare const convert: (createElement: CreateElement, markdown: string, option: Option) => any;
export default convert;

@@ -8,53 +8,30 @@ "use strict";

const remark_parse_1 = __importDefault(require("remark-parse"));
const remark_vdom_1 = __importDefault(require("remark-vdom"));
const markdownToVDom = (markdown, plugins) => {
const p = [remark_parse_1.default, ...plugins, remark_vdom_1.default];
const u = p.reduce((acc, plugin) => {
if (plugin.name) {
return acc.use(plugin);
const remark_rehype_1 = __importDefault(require("remark-rehype"));
const rehype_vue_1 = __importDefault(require("./rehype-vue"));
const convert = (createElement, markdown, option) => {
var _a, _b;
const remarkPlugins = ((_a = option) === null || _a === void 0 ? void 0 : _a.remarkPlugins) || [];
const rehypePlugins = ((_b = option) === null || _b === void 0 ? void 0 : _b.rehypePlugins) || [];
const remarkVueOption = {
createElement,
components: option.components,
sanitizeScheme: option.sanitizeScheme,
};
// prettier-ignore
const plugins = [
remark_parse_1.default,
...remarkPlugins,
remark_rehype_1.default,
...rehypePlugins,
[rehype_vue_1.default, remarkVueOption]
];
const processor = plugins.reduce((pipe, plugin) => {
if (Array.isArray(plugin)) {
return pipe.use(plugin[0], plugin[1] || {});
}
return acc.use(plugin.plugin, plugin.config);
return pipe.use(plugin);
}, unified_1.default());
const file = u.processSync(markdown);
return file.contents;
const { contents } = processor.processSync(markdown);
return contents;
};
const isFunc = (customComponent) => typeof customComponent === 'function';
const isVText = (vdom) => vdom.type === 'VirtualText';
const isVNode = (vdom) => vdom.type === 'VirtualNode';
const vdomToVNode = (createElement, vdoms, parent, option) => {
var _a, _b, _c;
const nodes = [];
for (let index = 0; index < vdoms.length; index++) {
const vdom = vdoms[index];
// VirtualText has no tag
if (isVText(vdom)) {
nodes.push(vdom.text);
continue;
}
if (!isVNode(vdom)) {
continue;
}
const children = ((_a = vdom.children) === null || _a === void 0 ? void 0 : _a.length) > 0 ? vdomToVNode(createElement, vdom.children, vdom, option) : [];
// get custom component
const tagName = (_b = vdom.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase();
const customComponentOpt = option.components[tagName];
const customComponent = isFunc(customComponentOpt) ? customComponentOpt(vdom, parent) : customComponentOpt;
if (customComponent) {
const node = createElement(customComponent, {
props: vdom.properties.attributes,
}, children);
nodes.push(node);
continue;
}
const node = createElement(tagName, {
attrs: (_c = vdom.properties) === null || _c === void 0 ? void 0 : _c.attributes,
}, children);
nodes.push(node);
}
return nodes;
};
const convert = (createElement, markdown, option) => {
const tree = markdownToVDom(markdown, option.remarkPlugins);
return vdomToVNode(createElement, [tree], undefined, option);
};
exports.default = convert;

@@ -20,30 +20,24 @@ "use strict";

const mockH = jest.fn().mockImplementation((...args) => args);
const vnodes = convert_1.default(mockH, markdown, { components: {}, remarkPlugins: [] });
const vnodes = convert_1.default(mockH, markdown, {});
expect(vnodes).toEqual([
'div',
{},
[
'div',
{ attrs: undefined },
['h1', {}, ['title']],
'\n',
['p', {}, ['plain text.']],
'\n',
['h2', {}, ['sub title']],
'\n',
[
['h1', { attrs: undefined }, ['title']],
'\n',
['p', { attrs: undefined }, ['plain text.']],
'\n',
['h2', { attrs: undefined }, ['sub title']],
'\n',
'ul',
{},
[
'ul',
{ attrs: undefined },
[
'\n',
['li', { attrs: undefined }, ['list1']],
'\n',
[
'li',
{ attrs: undefined },
['list2 with ', ['img', { attrs: { alt: 'image', src: 'https://example.com/hoge.jpg' } }, []]],
],
'\n',
['li', { attrs: undefined }, ['list3']],
'\n',
],
'\n',
['li', {}, ['list1']],
'\n',
['li', {}, ['list2 with ', ['img', { alt: 'image', src: 'https://example.com/hoge.jpg' }, undefined]]],
'\n',
['li', {}, ['list3']],
'\n',
],

@@ -50,0 +44,0 @@ ],

import Vue from 'vue';
import { Option } from './convert';
declare const _default: (_option?: Option) => import("vue/types/vue").ExtendedVue<Vue, unknown, unknown, unknown, {
declare const _default: (option?: Option) => import("vue/types/vue").ExtendedVue<Vue, unknown, unknown, unknown, {
markdown: string;
}>;
export default _default;

@@ -8,8 +8,3 @@ "use strict";

const convert_1 = __importDefault(require("./convert"));
exports.default = (_option) => {
var _a, _b;
const option = {
remarkPlugins: ((_a = _option) === null || _a === void 0 ? void 0 : _a.remarkPlugins) || [],
components: ((_b = _option) === null || _b === void 0 ? void 0 : _b.components) || {},
};
exports.default = (option) => {
return vue_1.default.extend({

@@ -19,6 +14,5 @@ name: 'markduck-root',

render(h) {
const nodes = convert_1.default(h, this.markdown, option);
return h('div', nodes);
return convert_1.default(h, this.markdown, option);
},
});
};
{
"name": "markduckjs",
"version": "0.0.5",
"version": "0.0.6",
"description": "Render markdown with your Vue components.",

@@ -36,6 +36,10 @@ "main": "lib/index.js",

"dependencies": {
"@types/virtual-dom": "^2.1.0",
"@mapbox/hast-util-table-cell-style": "^0.1.3",
"@mapbox/rehype-prism": "^0.3.1",
"hast-to-hyperscript": "^7.0.4",
"hast-util-sanitize": "^2.0.1",
"remark-parse": "^7.0.2",
"remark-vdom": "^8.0.0",
"remark-rehype": "^5.0.0",
"unified": "^8.4.2",
"unist-util-visit": "^2.0.1",
"vue": "^2.6.11",

@@ -42,0 +46,0 @@ "vue-hot-reload-api": "^2.3.4"

@@ -36,2 +36,4 @@ <div align="center">

import gemojiToEmoji from 'remark-gemoji-to-emoji';
import rehypePrism from '@mapbox/rehype-prism';
import 'prismjs/themes/prism.css';

@@ -41,3 +43,3 @@ export default {

return {
markdown: '# your markdown'
markdown: '# your markdown :duck:',
};

@@ -49,7 +51,8 @@ },

remarkPlugins: [gemojiToEmoji],
rehypePlugins: [rehypePrism],
components: {
ul: UnorderedList, // register your components!
ul: UnorderedList,
li: ListItem,
img: (vdom, parent) => { // you can register it via function
if (vdom.properties.attributes.alt) {
img: nodeData => {
if (nodeData.attrs.alt) {
return FigureImage;

@@ -77,3 +80,3 @@ }

```ts
type ComponentRegisterFunc = (node: VNode, parentNode?: VNode) => VueConstructor<Vue> | undefined;
type ComponentRegisterFunc = (data: VNodeData) => VueConstructor<Vue> | undefined;

@@ -96,3 +99,3 @@ type ComponentRegisterOption = {

`Array` of `Plugin` or `{ plugin: Plugin, config: Settings }`
`Array` of `Plugin` or `[Plugin, Settings]`
(`Plugin` and `Settings` are from [Unified](https://github.com/unifiedjs/unified).)

@@ -104,2 +107,9 @@

### rehypePlugins
Same as remarkPlugins.
Rehype plugins will run after remarkPlugins.
### sanitizeScheme
## Demo

@@ -112,1 +122,10 @@

```
## Flow of conversion from markdown to Vue
```
remark-parser remark-rehype createElement
your markdown -> mdast -> hast -> vue
↑ ↑
your remark plugin your rehype plugin
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc